diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..eccd3e14 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: ca4708850f7c797e7d86f54dddea2506 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..548ab56a --- /dev/null +++ b/404.html @@ -0,0 +1,646 @@ + + + + + + + + + + + Page not found — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Page not found

+ +
+
+ +
+
+
+ + + + +
+ +
+

Page not found#

+

Sorry, the page you were looking could not be found. +Please use the search function to look for information in the documentation. +For any issues, please contact us.

+
+ + + + +
+ + + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..8b0d766d --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.neuroml.org \ No newline at end of file diff --git a/Devdocs/DevSOP.html b/Devdocs/DevSOP.html new file mode 100644 index 00000000..b5c6e89d --- /dev/null +++ b/Devdocs/DevSOP.html @@ -0,0 +1,824 @@ + + + + + + + + + + + Contribution guidelines — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Contribution guidelines#

+

Thank you for your interest in contributing to NeuroML. +Welcome!

+

This page documents the contribution guidelines for all NeuroML related repositories.

+

Please do remember that these are guidelines but not rules that must be strictly followed. +We think these are reasonable ideas to follow and they help us maintain a high code quality while making it easier and more efficient for all of us to work together. +However, there may be cases where they can not be followed, and that’s fine too.

+
+

Code of conduct#

+

All NeuroML projects are governed by the Code of Conduct. +By participating, you are expected to uphold this code. +Please report unacceptable behaviour to the moderators of the communication channel you are in.

+
+
+

Structure of repositories#

+ +

You can find links to these on the respective pages for each software tool.

+

The NeuroML standard itself (schema and ComponentType definitions) is housed in its own repository here.

+

(devdocs:devsop:repos:zenhub)

+
+

Kanban board on Zenhub#

+

An overview of the various repositories, tasks, issues, and so on can be seen on the NeuroML Kanban board on Zenhub.

+
+
+
+

Versioning#

+

All NeuroML repositories (including the standard) follow Semantic versioning. +This means that the version string consists of three components: MAJOR.MINOR.PATCH:

+
    +
  • the MAJOR version is incremented when incompatible API changes are made,

  • +
  • the MINOR version is incremented when functionality is added in a backwards compatible manner, and

  • +
  • the PATCH version is incremented when backwards compatible bug fixes are made.

  • +
+
+
+

Git branches#

+
    +
  • Please develop against the development branch in all repositories. +This branch is merged into master via a pull request when a new release is made. +This ensures that all tests are run at each step to verify correctness. +As a result, the master branch of all repositories holds the stable version of the standard and tools, while the development branch holds the next, unstable version that is being worked upon.

  • +
  • For branch names, please consider using the Git flow naming convention (not mandatory but strongly suggested):

    +
      +
    • prefix feature branches with feat/ or enh/ (for enhancement)

    • +
    • prefix bugfix branches with bugfix/ or fix/

    • +
    • pull requests addressing specific tickets may also mention them in the branch name. E.g., bugfix/issue-22.

    • +
    +
  • +
+
+
+

Git commits#

+

Git commit messages are extremely important because they allow us to nicely track the complete development history of the project. +Here are some guidelines on writing good commit messages:

+
    +
  • Each commit should ideally only address one issue. +It should be self-contained (should not group together lots of changes). +Tip: use git add -p to break your work down into logical, small commits).

  • +
  • Write good commit messages. +Read this post to see how to write meaningful, useful commit messages and why they are important.

  • +
  • We strongly suggest using the Conventional Commit specification. +In short:

    +
      +
    • Each commit is of the form <type>[optional scope]: description, followed by the text body of the commit after a blank line, and then any optional references etc. as footer.

    • +
    • The type can be one of: fix, feat, build, chore, ci, docs, refactor, perf, test, and so on depending on what the commit is doing.

    • +
    • Any backwards incompatible, breaking change must be clearly noted in the commit using the BREAKING CHANGE phrase. +This corresponds to a major version update (as noted above in the versioning section).

    • +
    +
  • +
+
+
+

Code style: Java#

+

TODO

+
+
+

Code style: Python#

+
    +
  • While Python 2 is still supported even though it is no longer supported by the Python community, given that most Python modules (numpy/scipy/matplotlib/sphinx) have dropped support for this deprecated Python version, NeuroML will also drop support in the near future. +Therefore, we strongly suggest using Python 3.

  • +
  • For Python repositories, please use Black to format your code before committing and submitting a pull request.

  • +
  • We also strongly suggest linting using flake8.

  • +
  • Please use type hints in your code and run mypy to test it for correctness. +You can see the mypy cheatsheet to quickly see how to do this. +Since NeuroML is currently still supporting Python 2, we use the Python 2 style to maintain compatibility (this also works with Python 3).

  • +
  • Deprecations should be clearly noted in the code, and in the commit message. +You may use the Sphinx deprecated directive along with the Python DeprecationWarning, for example.

  • +
+
+
+

Documentation#

+

All tools include their own documentation in their repositories. +Please feel free to improve this documentation and submit pull requests.

+

When contributing fixes and enhancements, please remember to document your classes/functions and code in general. +Not only does this allow others to understand your code, it also allows us to auto-generate documentation using various tools.

+
    +
  • For the Java repositories, please use the standard Javadoc syntax.

  • +
  • For the Python repositories, please document your code using the standard Sphinx reStructuredText system. +For functions and so on, you can use the provided fields.

  • +
+

Where applicable, please add examples and so on to the software documentation to ensure that users can find the information quickly. +Additionally, please remember to consider if this primary NeuroML documentation here needs to be updated.

+

Please use Semantic Line Breaks wherever possible.

+
+
+

Testing#

+
    +
  • Before submitting a pull request, please run the various tests to confirm your changes. +You can see how they are run in the various GitHub workflow files (in the .github/workflows/ folder in each repository). +They will be run on all pull requests automatically so you can also verify your changes there.

  • +
  • For a new feature addition, please remember to include a unit test.

  • +
  • For a bug fix, please include a regression test.

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Devdocs/Devdocs.html b/Devdocs/Devdocs.html new file mode 100644 index 00000000..7ab566bd --- /dev/null +++ b/Devdocs/Devdocs.html @@ -0,0 +1,673 @@ + + + + + + + + + + + Overview — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Overview

+ +
+
+ +
+
+
+ + + + +
+ +
+

Overview#

+

This section will contain information for those who wish to contribute to the development of the NeuroML standard and associated tools.

+

An overview of the NeuroML release process can be found here.

+

The relationship of NeuroML to a number of other tools and standards in computational neuroscience, +and the practical steps taken thus far to ensure interoperability, can be found here.

+

The following project Kanban boards are used to consolidate issues:

+
    +
  • NeuroML: for all repositories under the NeuroML GitHub organization

  • +
  • LEMS: for all repositories under the LEMS GitHub organization

  • +
  • NeuralEnsemble: for all NeuroML related repositories in the Neural Ensemble GitHub organization

  • +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Devdocs/InteractionOtherBits.html b/Devdocs/InteractionOtherBits.html new file mode 100644 index 00000000..6fa6523d --- /dev/null +++ b/Devdocs/InteractionOtherBits.html @@ -0,0 +1,723 @@ + + + + + + + + + + + Interaction with other languages and standards — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Interaction with other languages and standards

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Interaction with other languages and standards#

+
+

Needs work

+

TODO: Add more information to each of these

+
+
+

PyNN#

+

NeuroML/NeuroML2#73

+
+
+

SBML#

+

OpenSourceBrain/SBMLShowcase

+
+
+

Sonata#

+

https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1007696

+
+
+

NineML & SpineML#

+

OpenSourceBrain/NineMLShowcase

+
+
+

ModECI MDF#

+

http://www.modeci.org/

+
+
+

SWC#

+

http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html +http://www.neuromorpho.org/myfaq.jsp

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Devdocs/ReleaseProcess.html b/Devdocs/ReleaseProcess.html new file mode 100644 index 00000000..c2b83658 --- /dev/null +++ b/Devdocs/ReleaseProcess.html @@ -0,0 +1,780 @@ + + + + + + + + + + + Release Process — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Release Process

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Release Process#

+
+

Overview#

+

In general, work is carried out in the development branches of the main NeuroML repositories +and these are merged to master branches on a new major release, e.g. move from NeuroML v2.1 to v2.2.

+

A single page showing the status of the automated test as well as any open Pull Requests on all of the core NeuroML repositories can be found here.

+
+
+

Steps for new major release#

+

These are the steps required for a new release of the NeuroML development tools.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Task

Version this was last done

Commit final stable work in development branches

v2.3

Make releases (not just tag - generates DOI) previous development versions of individual repos

v2.3

Increment all version numbers - to distinguish release from previous development version

v2.3

Test all development branches - rerun GitHub Actions at least once

v2.3

Recheck all READMEs & docs

v2.3

Run & check test.py in NeuroML2 repo

v2.3

Check through issues for closed & easily closable ones

v2.3

Update version in documentation pages

v2.3

Update HISTORY.md in NeuroML2

v2.3

pylems: Update README; Merge to master; Tag release; Release to pip

v2.3

libNeuroML: Update README; Retest; Merge to master; Tag release; Release to pip; Check installation docs

v2.3

pyNeuroML: Update Readme; Tag release; Release to pip

v2.3

NeuroMLlite: Update Readme; Tag release; Release to pip

v2.3

Java repositories (jNeuroML, org.neuroml.* etc.): Merge development to master; Tag releases

v2.3

Rebuild jNeuroML & commit to jNeuroMLJar and use latest for jNeuroML for OMV

v2.3

Add new binary release on NeuroML/jNeuroML

v2.3

Update version used in neuroConstruct

v2.3

Update docs on http://docs.neuroml.org

v2.3

Update version on COMBINE website

v2.2

ANNOUNCE (mailing list, Twitter)

v2.2

Increment version numbers in all development branches

v2.3

DOI on Zenodo

v2.3

Update NeuroML milestones

v2.2

New release of neuroConstruct

v2.3

Test toolchain on Windows…

v2.0

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Devdocs/UpdatingStandard.html b/Devdocs/UpdatingStandard.html new file mode 100644 index 00000000..0a42a839 --- /dev/null +++ b/Devdocs/UpdatingStandard.html @@ -0,0 +1,752 @@ + + + + + + + + + + + Making changes to the NeuroML standard — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Making changes to the NeuroML standard#

+

The NeuroML standard is stored in two sets of files, each serving a specific purpose:

+
    +
  • the NeuroML XML Schema Definition (XSD) file: this specifies the structure of a valid NeuroML XML file: what XML tags may be used and the how they are related

  • +
  • the NeuroML LEMS ComponentType definition XML files: these include the definitions of the NeuroML standard ComponentTypes in LEMS constructs, which include the mathematical details underlying these ComponentTypes

  • +
+

These files are housed in the NeuroML repository.

+

The XSD schema file is used to validate NeuroML XML files, as shown in the page on validating NeuroML files. +Further, the NeuroML Python model in libNeuroML is also generated from the XSD file using the generateDS utility.

+

The LEMS ComponentType definition XML files are also used for a series of additional validation tests, and since they include the details of the underlying dynamics for all ComponentTypes, they are also used for the simulation of NeuroML models either using the reference LEMS interpreter, jLEMS, or through automated code generation for supported simulation platforms (via jNeuroML). +Additionally, the LEMS definition files are also used the generate the human readable schema documentation included in this documentation resource.

+

The two sets of files are therefore, tightly coupled. +Any changes to the XSD file must also be followed by corresponding changes to the LEMS definition files.

+
+

Procedure#

+
+

PR waiting

+

TODO: A pull request to include the transfer_docs_to_xsd.py script in the repository is in review here: NeuroML/NeuroML2#172

+
+

The suggested way of making changes to these files is via pull requests to the NeuroML repository which will undergo review by the NeuroML editorial board and the development team. +As noted in the general contribution guidelines, the development branch tracks the next release of the NeuroML standard. +So, all pull request must be made against the development branch.

+
    +
  • New ComponentTypes, and their elements (parameters, variables etc.) that are added in the LEMS definition XML files should be properly documented.

  • +
  • After both sets of files have been modified, please run the transfer_docs_to_xsd.py script in the scripts folder to copy documentation over from the XML files to the XSD schema file. This script will also run basic sanity checks to ensure that all ComponentTypes in the LEMS XML definition files are represented in the XSD schema file and vice-versa.

  • +
  • Please run xmllint on the files to ensure they are formatted correctly.

  • +
  • Please make individual commits for changes to the XSD file, and the XML files. This ensures that their change history is clearly maintained.

  • +
+
+
+

Regenerating schema documentation#

+

Once the pull request has been merged in the NeuroML repository, the human readable schema documentation included in this documentation resource must be updated. +This is done by running the generate-jupyter-ast.py script included in the documentation source repository. +This will read the LEMS XML definition files and regenerate the corresponding documentation pages. +A pull request can then be opened with the updated pages.

+
+
+

Updating the Java API: org.neuroml.model#

+

TODO: Document what needs to be done for NeuroML/org.neuroml.model

+
+
+

Updating the Python API: libNeuroML#

+
+

PR waiting

+

TODO: A pull request to include the regenerate-nml.sh script in the repository is in review here: NeuralEnsemble/libNeuroML#110

+
+

Any changes to the XSD schema file require regeneration of the Python object model in libNeuroML:

+
    +
  • copy over the updated XSD schema file to the neuroml/nml/ directory in the development branch

  • +
  • commit the new XSD file

  • +
  • run the regenerate-nml.sh script to regenerate and reformat nml.py

  • +
  • build and install libNeuroML into a new virtual environment

  • +
  • run all tests using pytest

  • +
  • run all examples and ensure that they run correctly (please see the GitHub actions workflow for more information)

  • +
  • if all checks pass successfully, a pull request can be opened

  • +
+
+
+

Updating the C++ API#

+

TODO: Document what needs to be done for NeuroML/NeuroML_API

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/2012-Edinburgh.html b/Events/2012-Edinburgh.html new file mode 100644 index 00000000..b3a92aa8 --- /dev/null +++ b/Events/2012-Edinburgh.html @@ -0,0 +1,1007 @@ + + + + + + + + + + + March 2012: Fourth NeuroML Development Workshop — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

March 2012: Fourth NeuroML Development Workshop#

+

Convergence in Computational Neuroscience 2012 +Joint BrainScaleS CodeJam/NeuroML workshop, Edinburgh, 12-16th March

+

The NeuroML Development Workshops and the BrainScaleS (previously FACETS) CodeJams have been two important initiatives in recent years for developers of tools in computational and systems neuroscience to present their latest work, exchange ideas and work at achieving interoperability between software applications for investigating brain function. +This year these groups held a joint workshop (Convergence in Computational Neuroscience) on March 12th-16th in the Informatics Forum in Edinburgh, UK. +The meeting was held at the Informatics Forum in Edinburgh, UK, from 12th to 16th March 2012.

+
+

Meeting report#

+

Note: details of the meeting activities from Wednesday 14th to Friday 16th are available on the NeuralEnsemble.org webpage.

+
+

Monday 12th March: NeuroML Development Workshop Day 1#

+
+

Morning session: Current state of NeuroML 2 development & relationship to other initiatives#

+

Chair: Andrew Davison

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time

Session

Speaker

09:00

Welcome & goals of meeting

+

Angus welcomed attendees, thanking in particular out local organisers at University of Edinburgh, Mike Hull and Mika Pelko!

+

Angus Silver

09:05

Update on latest developments in NeuroML 2/LEMS (PPT)

+

Padraig presented an introduction to NeuroML, starting with an overview of the modular nature of NeuroML v1.x, advantages of the use of XML, examples of neuronal models in NeuroML, current tools which support the language, (including the recently added NeuroMorpho.org and Channelpedia).

+

The requirements for v2.0 were presented. Explicit definitions of model component behaviour allows description of the dynamics of model components in a simulator independent, machine readable way. The relationship between LEMS and NeuroML2 was discussed. A short overview of NeuroML 2.0 was given including dimensions/units. Example of adaptive exponential integrate and cell network was presented. An overview of libNeuroML was given. Export to NEURON, neuroConstruct, interaction with SBML was shown.

+

Padraig Gleeson

09:30

Introduction to NineML & libNineML (PDF)

+

Mike gave an introduction to the NineML object model and libNineML. The INCF Task Force in Multiscale Modelling created the language, consisting of an Abstraction Layer and User Layer. Mike’s presentation focused on the abstraction layer which contains many terms for the object model. Core object in the Abstraction layer were presented: ComponentClass, Interface with Parameters, Ports (AnalogPorts, EventPorts and Reduce Ports), Dynamics with StateVariables and a Regime Transition Graph (with Transitions, StateAssignments, Aliases).

+

libNineML (in Python) loads and saves models from/to XML to/from Python that helps with code generation, turns models into NEST, NEURON and PyNN.

+

Mike Hull

10:00

The COMBINE Initiative (PDF)

+

Nicolas presented the Combine Initiative: Standards for describing the whole life-cycle of modelling. Different communities favour different types of models that are more suited for their domain. Current standardisation efforts depend on the initial people, individual funding structure, IP issues. Specifications, API’s, test-suites, etc. really need industry-grade support which is not compatible with standard academic usages and possibilities.

+

The vision of COMBINE is to pave the space of model descriptions with coordination of standard development (without interference with the development). There are criteria for inclusion in the core COMBINE standards: new standards must be different from those already included, described in technical specification documents, free, open, developed and used by more than one team, democratically elected members, mature software support including API, and must be actively developed.

+

COMBINE organises joint meetings replacing standards specific ones (e.g. SBML Hackathon). Next COMBINE meeting is in Toronto in August. HARMONY for hacking will be in Maastricht in May.

+

Nicolas le Novere

10:30

Coffee

11:00

The International Neuroinformatics Coordinating Facility

+

Sean presented the motivation for, current structure and the aims of the INCF. The goal of neuroscience is to understand the brain. We’re at a crisis point in understanding disorders. Big Pharma is pulling out of neuroscience due to the high cost and risk of understanding these disorders. Past centuries have focused on obtaining observations. More recently, models were used to understand these observations. Today we have eScience as a new way of handling large-scale data, modelling, simulations, linking data, etc. One of the INCF’s goals is to transform neuroscience into an eScience from level of molecules to clinic.

+

Integration of databases is a goal, which requires standardized data formats. There are 16 member countries in INCF. He gave an introduction to the 4 programs from the past few years: Digital Brain Atlasing, Multi-Scale Modeling, Ontologies of Neural Structures and Standards for Datasharing.

+

He discussed future plans for the INCF “Cyberinfrastructure”, including a discussion of the planned INCF cloud “Dropbox” for data which could include metadata tags enabling global search.

+

Sean Hill

11:30

Collaborative Modelling Repository update

+

Padraig presented the initial work towards an open source, collaborative repository for NeuroML models, the Open Source Brain project. A preliminary version of this is avaliable here. It will be based on a version control repository (initially Mercurial) storing the model files. It will have automatic generation of online documentation of the models from ChannelML, MorphML, etc. Connectivity matrices for network connections, etc. can be generated for models which are stored in neuroConstruct format. NeuroLex IDs can be used to identify cells and channels to other resources. Feedback on the initial implementation was welcomed.

+

Padraig Gleeson

12:00

Open discussion on model specification initiatives

+

Differences were pointed out between INCF and COMBINE approaches to standards development. IEEE provides an infrastructure for review, etc. Nicolas discussed the burdens of obtaining “official” standards board recognition. Many of the COMBINE procedures imitate W3C procedures. A good standard is one that works. COMBINE criteria don’t say anything about the standard document itself.

+

13:00

Lunch

+
+
+

Afternoon session: Specification of detailed biophysical components in NeuroML 2/LEMS#

+

Chair: Sharon Crook

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time

Session

Speaker

14:00

Representing channels, synapses & conductance based models (PDF)

+

Robert gave a presentation on ways to represent synapses and conductances. He defined the Nernst equation with XML based on Hille’s description. It is still not clear how some things should be done, in particular how to handle dimensions and units. Currently, dimensions are defined and then assertions about relationships among dimensions can be made. Units are not defined until NeuroML is written (with numerical values, e.g. -70mV). There was some discussion of how dimensions should be defined. Physicists solved this problem by developing SI units. Both space and no space between values and units are allowed in LEMS. There was some discussion of how events can be handled in LEMS.

+

Robert Cannon

14:20

Experiences with using NeuroML 2

+

Avrama gave a brief report of her hands on experience with using NeuroML 2. She has a medium spiny projection neuron model which she’s translating to GENESIS. She didn’t want to use a GUI unless absolutely necessary and has been manually editing the XML. Many of the (non calcium dependent) channels have already been converted to NeuroML 2. She can only run single compartment versions of her model since LEMS doesn’t yet support multi compartmental models. She has produced some some multi segment morphologies in NML2, even though these can’t be used in LEMS based simulations yet. She requires a way to specify distance from the soma. Another difficulty is not being able to define a template (dendritic) subbranch and add it multiple times to the cell. She will add spines later. Calcium dependent channels are a work in progress in NeuroML v2.0, but some useful simulations have already been done with her developing model.

+

Avrama Blackwell

14:40

Implementing cerebellar models in PyNEURON, neuroConstruct & NeuroML

+

Sergio is developing cerebellar models (Golgi cells and granular cells) in a network of granule layer. Solinas S, Nieus T and D`Angelo E (2010) A realistic large-scale model of the cerebellum granular layer predicts circuit spatio-temporal filtering properties. Frontiers in Cellular Neuroscience (link) gives an overview of the network. There were improvements made to the model in 2011 and it was translated to Python Neuron for parallel simulation on cluster. Added gap junctions, more realistic inputs. Python eased improvements to the model.

+

Sergio Solinas

15:00

Large scale cortical models for studying LFPs (PPT)

+

Richard presented his work on developing large scale cortical models for studying Local Field Potentials. What network properties cause pathological dynamics? Much data comes from electrodes in vitro. Gaute Einevol’s work looks at how dendritic structure affects the field potentials in a network (Linden et al Neuron 2010). Richard focused on Bush and Sejnowski J Neurosci Methods 1993 method to reduce model and see what the LFP looks like (and compared to Linden data). Then since it looked pretty good he created a network of these reduced models for simulation and analysis. Then looked at results from Utah array in Matlab. Next he’ll add Gaussian connectivity and some patches and long range connections.

+

Richard Tomsett

15:15

Coffee

15:30

Break out sessions

+
    +
  • Channel and synapse specifications

  • +
  • Proposed structure for abstract neuron model hierarchy

  • +
+

17:30

Reconvene and presentated discussions

18:00

Close

+
+
+
+

Tuesday 13th March: NeuroML Development Workshop Day 2#

+
+

Morning session: Representing morphologies/support for detailed neuronal simulators/relationship to connectomics initiatives#

+

Chair: Michael Hines

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time

Session

Speaker

09:00

The Neural Tissue Simulator(PDF)

+

James presented his work on the Neural Tissue Simulator, much of which was contained in the recent publication: Kozloski J and Wagner J (2011) An ultrascalable solution to large-scale neural tissue simulation. Frontiers in Neuroinformatics. 5:15. (link).

+

The key goals of this work are: to develop a simulator capable of testing mappings to various machine architectures, both parallel and multithreaded; to develop support for high level, abstract model definitions and simulation specifications; and to create an extensible simulator, able to map arbitrary, domain level models directly to a variety of data arrangements and computational implementations.

+

James discussed the process of defining the model (using the Model Definition & Graph Specification Languages), how the model elements are partitioned on the computing resources, and how these elements communicate during simulation to solve the model equations. He discussed the specific case of simulating cortical columns when synapses were determined through contact detection algorithms. He also presented some results for how the simulator scales for larger networks. The Neural Tissue Simulator is not currently publicly available, but James is keen to make it available, and to build a community of users. NeuroML support is also planned

+

James Kozloski

09:30

The Blue Brain Project

+

Eilif presented an overview of the Blue Brain Project’s efforts to reverse engineer a P14 Rat non-barrel somatosensory cortical column. Based on a database of anatomical reconstructions, electrophysiology, etc. they will fill the cortical column with cells based on known location, probability distributions. Morphologies for those classes of cells are taken from library of cells called a collage with some rules about how they fit in based on constraints from reconstructions. Some of these cells have been “repaired” due to axon cuts in reconstructions.

+

Functional circuits are also based on biological data. Electrical behaviors are based on classifications based on firing patterns observed in experiments. This is combinatorial since each morphological class has a number of possible firing patterns. They use genetic algorithm to adjust parameters which are set up based on what is known (gene expression, etc). Channelome project uses cell culture and automated patch clamp by robot and then automated model fitting for data that are then posted to Channelpedia. Channels there are available in ChannelML. Synaptic parameterization and validation for functional synapses are also based on database of recorded synaptic properties.

+

In silico model is compared to in vitro using same protocols as experiments. There was a standards and interoperability discussion: they are mostly using custom formats other than what they use with NEURON. Eilif welcomed greater support for more widely used standards.

+

Eilif Muller

10:00

Tools for the dense reconstruction of neuronal circuits

+

Moritz gave an overview of his recent work with Winfried Denk and Frank Briggman, which is continuing in his own lab. They have used Serial Block-Face Electron Microscopy (SBEM), to investigate the connectivity in blocks of neuronal tissue, which has been the subject of a number of recent publications, e.g. K.L. Briggman, Helmstaedter, M. and W. Denk, Wiring specificity in the direction-selectivity circuit of the mammalian retina. Nature 471, 183-188, 2011. (link).

+

He also discussed the application KNOSSOS which was developed to facilitate the reconstruction of neuronal morphologies from such data. While this tool uses a proprietary format for storing morphologies, it is open source and Mortiz was keen to integrate the application with other tools using NeuroML.

+

Moritz Helmstaedter

10:30

Coffee

11:00

The OpenWorm project: Using NeuroML in a highly detailed model of C. elegans (PPT)

+

Stephen presented the OpenWorm project. This ambitious project aims to build an in silico model of C. elegans. This well studied system with ~1000 cells and 302 identified neurons is an ideal system with which to attempt a full simulation of a living organism down to cellular scale. Many different approaches are being take in the project at the moment, including investigatin Smoothed Particle Hydrodynamics (SHP) to allow simulation of the interaction of the worm with its environment, and creating a new parallel (GPU based) simulator in Java which will support physical and electrical simulations. Full reconstructions of all of the cells are available in 3D and those of the neurons have been converted to NeuroML, which will form the basis of a simulation of the worm’s nervous system.

+

One of the concrete outcomes of code sprinting work on the fringes of the NeuroML/CodeJam meeting was the updated OpenWorm Browser, where the full cellular structure of the worm can be browsed in 3D.

+

Stephen Larson

11:30

Open discussion on tool support for large scale neural simulations

13:00

Lunch (provided)

+
+
+

Afternoon session: Best practices when implementing support for NeuroML in simulators#

+

Chair: Avrama Blackwell

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time

Session

Speaker

14:00

Introduction to SED-ML (PDF)

+

Dagmar gave an overview of the motivation behind the development of SED-ML, the Simulation Experiment Description language , the current status of the specification, and some of the uses it has been put to so far. It compliments a model description in SBML or NeuroML and allow specification of the simulation algorithm used to run the model, any changes made to the parameters specified in the model description, the simulation duration, what variables were saved during the simulation, and how that data was processed.

+

In SED-ML you can define a uniform time course with an initial time and start and end time. This needs to be expanded to other possible time courses. Multiple tasks (simulations) can be defined. For example, run the original database model and the changed model. Output can be set up as 2D or 3D plots or a datatable. SED-ML has an elected board of editors. Contribution to SED-ML is encouraged. Sourceforge can be used for feature requests and this will move forward as people contribute.

+

Dagmar Waltemath

14:20

Introduction to CNO: an ontology for annotating computational neuroscience models (PDF)

+

Yann presented an introduction to CNO: an ontology for annotating computational neuroscience models. All classes must have a unique identifier, a label (name) and a human-readable definition. Relationships among classes are specified with relations. Examples are subsumption relations, associative relations, etc. We then can associate this semantic information with parts of XML files.

+

Yann le Franc

14:40

NeuroLex & NIF update (PPT)

+

Stephen gave us an update on NeuroLex and the Neuroscience Information Framework (NIF). We need for an online parts list for the brain. NeuroLex is built on Wiki technology with extra functionality to create structured knowledge where anyone can create or edit. It currently as about 18,000 concepts. NIF funds curators from NIH money and also looks for volunteers. In the future they want to dominate Google searches with NeuroLex terms. Looking to Yelp for how they display info including images and related queries and such. Some place for community comments. Another goal is to expose high quality linked data with example of an open linked data graph.

+

Stephen Larson

15:00

libSBML and SBML L3 (PDF)

+

Sarah gave a brief overview of libSBML and SBML Level 3. libSBML, which provides an API for creating, editing and saving SBML in many languages (e.g. C++, Python, Java, Ruby, Perl) has been instrumental in the growth of the number of applications supporting SBML.

+

SBML Level 3 has a modular architecture, featuring a core specification (roughly in line with previous SBML releases) and a number of specialist packages, which applications can choose to support or not. Examples of these packages incluse layout for storing the spatial topology of a model’s network diagram, comp for defining how a model is composed from other models and spatial for describing models that involve a spatial component. libSBML already has a generic framework to support extensions for generic packages.

+

Sarah Keating

15:15

Coffee

15:30

Break out sessions

+
    +
  • How best to map generic model descriptions to a given simulator

  • +
  • Support for morphologies

  • +
+

17:30

Reconvene and presentated discussions

18:00

Close of meeting

+
+
+
+

Wednesday 14th March–Friday 16th March#

+

Full details of the meetings from Wed-Fri are available on the NeuralEnsemble.org webpage for the meeting.

+
+
+
+

Funding#

+

The NeuroML part of this workshop was made possible with funding from:

+
    +
  • The National Institutes of Health

  • +
  • Wellcome

  • +
  • The UK Neuroinformatics Node

  • +
  • The International Neuroinformatics Co-ordinating Facility (INCF)

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202103-Harmony.html b/Events/202103-Harmony.html new file mode 100644 index 00000000..90a2637d --- /dev/null +++ b/Events/202103-Harmony.html @@ -0,0 +1,735 @@ + + + + + + + + + + + March 2021: NeuroML hackathon at HARMONY 2021 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

March 2021: NeuroML hackathon at HARMONY 2021

+ +
+ +
+
+ + + + +
+ +
+

March 2021: NeuroML hackathon at HARMONY 2021#

+
+

Registration for the COMBINE initiative’s HARMONY 2021 meeting is free.

+

Register for the COMBINE: HARMONY 2021 meeting here. +Registration is free.

+
+

We will be running 3 online NeuroML hackathon sessions during the upcoming COMBINE: HARMONY 2021 meeting on 23-25th March. +The general theme of the sessions will be: learn to build, visualise, analyse and simulate your models using NeuroML.

+
+

Why take part?#

+

These hackathons will give members of the neuroscience community the chance to:

+
    +
  • Get high level introductions to the NeuroML language and tool chain

  • +
  • Meet the NeuroML core development team and editors

  • +
  • Find out the latest information on which simulators/applications support NeuroML

  • +
  • Open, discuss and work on issues related to converting your model to NeuroML, or supporting NeuroML in your simulator

  • +
  • Learn how to share your models with the community

  • +
+
+
+

Times and dates#

+

All sessions will be online and take place over 3 hours (9am-noon Pacific; 12-3pm EST time; 4-7pm UK/UTC; 5-8pm CET, 9:30pm-12:30am IST; note non-standard US/EU time differences that week). +The broad focus of each of the sessions (dependent on interests of attendees) is:

+
    +
  • Tues 23rd March: Introduction to NeuroML, general questions about usage

  • +
  • Wed 24th March: Detailed cell/conductance based models (e.g. converting channels to NeuroML)

  • +
  • Thus 25th March: Abstract/point neuron networks including PyNN interactions

  • +
+
+
+

Registration#

+

To take part in the hackathon, please register here for the HARMONY meeting (registration is free). +You will get sent details to access the agenda, which will have links to the Zoom sessions for each of the days.

+
+
+

Open an issue beforehand!#

+

While it will be possible to raise and discuss new issues at the hackathons, it will be easier to manage and plan work/discussions if you open an issue with a description of the problem you are trying to address at: NeuroML/NeuroML2#issues.

+
+
+

Slack#

+

To aid communication with the community during (and after) the meeting, we have a Slack channel for NeuroML related discussions. +Please contact Padraig Gleeson for an invite.

+

We look forward to working with the community to drive further uptake of NeuroML compliant models and tools!

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202107-CNS2021.html b/Events/202107-CNS2021.html new file mode 100644 index 00000000..dc46b533 --- /dev/null +++ b/Events/202107-CNS2021.html @@ -0,0 +1,729 @@ + + + + + + + + + + + July 2021: NeuroML tutorial at CNS*2021 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

July 2021: NeuroML tutorial at CNS*2021

+ +
+ +
+
+ + + + +
+ +
+

July 2021: NeuroML tutorial at CNS*2021#

+
+

Register for the 30th Annual meeting of the Organization for Computational Neurosciences (OCNS).

+

Register for the CNS*2021 here.

+
+

We will be running a half day tutorial at the 30th annual meeting of the Organization for Computational Neurosciences (OCNS): CNS*2021.

+

The goal of the tutorial is to teach users to: build, visualise, analyse and simulate models using NeuroML.

+
+

Why take part?#

+

This tutorial is aimed at new and current NeuroML users. We will start with a quick introduction to the NeuroML standard and the associated software ecosystem, after which we will proceed to conduct hands-on sessions to show how one can build computational models with NeuroML.

+
+
+

Times and dates#

+ +
+
+

Registration#

+

To take part in the tutorial, please register here for the CNS*2021 meeting.

+
+
+

Pre-requisites#

+

The sessions will make use of the NeuroML Python tools. +Please follow the documentation to install them on your system if you wish to use them locally:

+ +

You can also use the interactive Jupyter notebooks from the documentation if you prefer (example). These can be run on Binder and Google Collab in your web browser and do not require you to install anything locally on your computer.

+
+
+

Slack#

+

To aid communication with the community during (and after) the meeting, we have a Slack channel for NeuroML related discussions. +Please contact Padraig Gleeson for an invite.

+

You can also contact the NeuroML community using one of our other channels.

+

We look forward to working with the community to drive further uptake of NeuroML compliant models and tools!

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202108-INCF-Training-Week.html b/Events/202108-INCF-Training-Week.html new file mode 100644 index 00000000..e314b6b6 --- /dev/null +++ b/Events/202108-INCF-Training-Week.html @@ -0,0 +1,737 @@ + + + + + + + + + + + August 2021: NeuroML tutorial at INCF Training Weeks — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

August 2021: NeuroML tutorial at INCF Training Weeks

+ +
+ +
+
+ + + + +
+ +
+

August 2021: NeuroML tutorial at INCF Training Weeks#

+

A NeuroML tutorial will be held at the Virtual INCF Neuroinformatics Training Weeks 2021.

+

This tutorial is intended for members of the research community interested in learning more about how NeuroML and its related technologies facilitates the standardization, sharing, and collaborative development of models.

+
+

Times and dates#

+

This tutorial will be offered twice during the Neuroinformatics Training Week: session 1 is targeted to participants residing in Europe, Africa, and the Americas while session 2 is targeted to participants residing in Asia and Australia.

+

Session 1:

+
    +
  • Dates: 23 Aug 2021

  • +
  • Time: : 11:00-15:00 EDT / 17:00-21:00 CEST

  • +
+

Session 2

+
    +
  • Dates: 26 Aug 2021

  • +
  • Time: 09:00-13:00 CEST / 16:00-20:00 JST / 17:00-21:00 AEST

  • +
+
+
+

Target audience#

+

Anyone who is already familiar with computational modelling, but is keen to standardise, share and collaboratively develop their models.

+
+
+

Agenda#

+
+

Part 1: Introduction to NeuroML#

+
    +
  • Overview of NeuroML

  • +
  • Introduce the NeuroML tool chain

  • +
  • Introduce main documentation

  • +
  • Related technologies and initiatives

  • +
+
+
+

Part 2: Hands on demonstrations of building and using NeuroML models#

+
    +
  • Izhikevich neuron hands on tutorial

  • +
  • Spiking neuron network tutorial

  • +
  • Single compartment HH neuron tutorial

  • +
  • Multi compartmental HH neuron tutorial

  • +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202109-COMBINE.html b/Events/202109-COMBINE.html new file mode 100644 index 00000000..fc62963e --- /dev/null +++ b/Events/202109-COMBINE.html @@ -0,0 +1,711 @@ + + + + + + + + + + + October 2021: NeuroML development workshop at COMBINE meeting — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

October 2021: NeuroML development workshop at COMBINE meeting

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

October 2021: NeuroML development workshop at COMBINE meeting#

+
+

Registration for the COMBINE 2021 meeting is free.

+

Register for the COMBINE 2021 meeting here. +Registration is free.

+
+

A NeuroML development workshop will be held as part of the annual COMBINE meeting in October 2021.

+

The general theme of the workshop is to discuss the current status of the NeuroML standard and the complete software ecosystem, and future development plans.

+
+

Times and dates#

+
    +
  • 13 October 2021

  • +
  • 8-11am PDT/11-2pm EST/4-7pm UK/5-8pm CET/8:30-11:30 IST

  • +
+
+
+

Target audience#

+

Everyone that is involved/interested in developing tools that use/integrate with NeuroML is encouraged to join.

+

Please register for the COMBINE meeting (free of charge) to receive access to the complete schedule of the meeting, including links to the various virtual meetings/sessions.

+
+
+

Agenda/minutes#

+

The agenda/minutes for the meeting can be found here.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202204-Harmony.html b/Events/202204-Harmony.html new file mode 100644 index 00000000..73396f33 --- /dev/null +++ b/Events/202204-Harmony.html @@ -0,0 +1,722 @@ + + + + + + + + + + + April 2022: NeuroML development workshop at HARMONY 2022 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

April 2022: NeuroML development workshop at HARMONY 2022

+ +
+ +
+
+ + + + +
+ +
+

April 2022: NeuroML development workshop at HARMONY 2022#

+
+

Registration for the COMBINE initiative’s HARMONY 2022 meeting is free.

+

Please register for the COMBINE HARMONY 2022 meeting here if you are coming to our NeuroML workshop. +Registration for HARMONY is free.

+
+

We will be running a NeuroML development workshop during the upcoming COMBINE network’s HARMONY 2022 meeting on Thus 28 April 2022. +This will be an opportunity for anyone interested in developing NeuroML or adding support for the format to their application talk about their work and hear about other developments.

+
+

Agenda#

+

The agenda for the meeting can be found here.

+
+
+

Times and dates#

+

The workshop will take place on Thus 28 April 2022 at 15:00-18:00 UTC (converter).

+
+
+

Registration#

+

To take part in the workshop, please register here for the HARMONY meeting (registration is free).

+

You will get sent details to access the HARMONY agenda, which will have links to the Zoom session for the NeuroML workshop.

+
+
+

Open an issue beforehand!#

+

While it will be possible to raise and discuss new issues at the workshop, it will be easier to manage and plan work/discussions if you open an issue with a description of the problem you are trying to address at: NeuroML/NeuroML2#issues.

+
+
+

Slack#

+

To aid communication with the community during (and after) the meeting, we have a Slack channel for NeuroML related discussions. +Please contact Padraig Gleeson for an invite.

+

We look forward to working with the community to drive further uptake of NeuroML compliant models and tools!

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/20220630-CNS2022.html b/Events/20220630-CNS2022.html new file mode 100644 index 00000000..5b7d9d17 --- /dev/null +++ b/Events/20220630-CNS2022.html @@ -0,0 +1,738 @@ + + + + + + + + + + + June 2022: NeuroML tutorial at CNS*2022 satellite tutorials — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

June 2022: NeuroML tutorial at CNS*2022 satellite tutorials

+ +
+ +
+
+ + + + +
+ +
+

June 2022: NeuroML tutorial at CNS*2022 satellite tutorials#

+

An online NeuroML tutorial will be held at the CNS*2022 satellite tutorials. +Registration for the satellite tutorials is free, but required.

+

This tutorial is intended for members of the research community interested in learning more about how NeuroML and its related technologies facilitates the standardization, sharing, and collaborative development of models.

+
+

Times and dates#

+ +
+
+

Target audience#

+

Anyone who is already familiar with computational modelling, but is keen to standardise, share and collaboratively develop their models.

+
+
+

Where#

+

The tutorial be done online via Zoom and will make use of the Open Source Brain v2 integrated web research platform.

+

Please register for the CNS*2022 satellite tutorials to receive the Zoom links.

+
+
+

Agenda#

+
+

Part 1: Introduction to NeuroML#

+
    +
  • Overview of NeuroML

  • +
  • Introduce the NeuroML tool chain

  • +
  • Introduce main documentation

  • +
  • Related technologies and initiatives

  • +
+
+
+

Part 2: Hands on demonstrations of building and using NeuroML models#

+
    +
  • Izhikevich neuron hands on tutorial

  • +
  • Spiking neuron network tutorial

  • +
  • Single compartment HH neuron tutorial

  • +
  • Multi compartmental HH neuron tutorial

  • +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202404-Harmony.html b/Events/202404-Harmony.html new file mode 100644 index 00000000..9ffe076d --- /dev/null +++ b/Events/202404-Harmony.html @@ -0,0 +1,722 @@ + + + + + + + + + + + April 2024: NeuroML hackathon at HARMONY 2024 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

April 2024: NeuroML hackathon at HARMONY 2024

+ +
+ +
+
+ + + + +
+ +
+

April 2024: NeuroML hackathon at HARMONY 2024#

+
+

Registration for the COMBINE initiative’s HARMONY 2024 meeting is free.

+

Please register for the COMBINE HARMONY 2024 meeting here if you are coming to our NeuroML workshop. +Registration for HARMONY is free.

+
+

We will be running a NeuroML workshop during the upcoming COMBINE network’s HARMONY 2024 meeting on Tues 9th April 2024 in London, entitled:

+

NeuroML hackathon: convert your neuron and network models to open, standardised, reusable formats

+

This will be an opportunity for developers of models in computational neuroscience to get an introduction to the aims and structure of NeuroML, a guide to the tools available for building/converting their models to NeuroML, and to receive hands on help with expressing their models (or other published models they are interested in) in NeuroML format, making them more open, accessible and reusable.

+
+

Agenda#

+

More details to follow

+
+
+

Times and dates#

+

More details to follow

+
+
+

Registration#

+

To take part in the workshop, please register here for the HARMONY meeting (registration is free).

+
+
+

Open an issue beforehand!#

+

While it will be possible to raise and discuss new issues at the workshop, it will be easier to manage and plan work/discussions if you open an issue with a description of the problem you are trying to address at: NeuroML/NeuroML2#issues.

+
+
+

Slack#

+

To aid communication with the community during (and after) the meeting, we have a Slack channel for NeuroML related discussions. +Please contact Padraig Gleeson for an invite.

+

We look forward to working with the community to drive further uptake of NeuroML compliant models and tools!

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/202407-CNS2024.html b/Events/202407-CNS2024.html new file mode 100644 index 00000000..6493dc91 --- /dev/null +++ b/Events/202407-CNS2024.html @@ -0,0 +1,737 @@ + + + + + + + + + + + July 2024: NeuroML tutorial at CNS 2024 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

July 2024: NeuroML tutorial at CNS 2024

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

July 2024: NeuroML tutorial at CNS 2024#

+
+

Registration for the annual meeting of the Organisation of Computational Neuroscience, CNS 2024, is open.

+

Please register for the CNS 2024 here.

+
+

We will be running a full day NeuroML tutorial during the annual meeting of the Organisation of Computational Neuroscience, 2024 meeting in Natal, Brazil from July 20–24.

+

Standardised, data-driven computational modelling with NeuroML using Open Source Brian

+

Data-driven models of neurons and circuits are important for understanding how the +properties of membrane conductances, synapses, dendrites and the anatomical connectivity +between neurons generate the complex dynamical behaviours of brain circuits in health and +disease. However, even though data and models are being made publicly available in recent +years and the use of standards such as Neurodata Without Borders (NWB) +and NeuroML to promote FAIR (Findable, Accessible, Interoperable +and Reusable) neuroscience is on the rise, development of data driven models remains +hampered by the difficulty of finding appropriate data and the inherent complexity involved in +their construction.

+

The Open Source Brain web platform (OSB) brings together +data, accompanying analysis tools, and computational models in a single, scalable resource. +It indexes repositories from established sources such as the DANDI data +archive, the ModelDB model sharing +archive, and GitHub to provide easy access to a +plethora of experimental data and models, including +a large number standardised in NWB and NeuroML formats

+

OSB also incorporates the NeuroML software ecosystem. NeuroML is an established +community standard and software ecosystem that enables the development of biophysically +detailed models using a declarative, simulator independent description. The software +ecosystem supports all steps of the model lifecycle and allows users to automatically +generate code and run their NeuroML models using a number of well established simulation +engines (NEURON/NetPyNE).

+

Read the NeuroML pre-print here: https://www.biorxiv.org/content/10.1101/2023.12.07.570537v1

+
+

Agenda#

+

In this tutorial, attendees will learn about:

+
    +
  • Finding data and models on OSB

  • +
  • NeuroML and its software ecosystem

  • +
  • Using NeuroML models on OSB

  • +
  • Building and simulating new NeuroML models constrained by the data on OSB

  • +
+

We will also provide assistance with advanced tasks, and discuss new features to further aid researchers.

+
+
+

Times and dates#

+

More details to follow

+
+
+

Registration#

+

To take part in the tutorial, please register here for CNS 2024.

+

We look forward to working with the community to drive further uptake of NeuroML compliant models and tools!

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Events/PastEvents.html b/Events/PastEvents.html new file mode 100644 index 00000000..7d3deba6 --- /dev/null +++ b/Events/PastEvents.html @@ -0,0 +1,663 @@ + + + + + + + + + + + Past NeuroML Events — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Past NeuroML Events

+ +
+
+ +
+
+
+ + + + +
+ +
+

Past NeuroML Events#

+

A number of developer workshops and editorial board meetings have been held since 2008 to coordinate and promote the work of the NeuroML community. These are listed here.

+

There has been significant NeuroML involvement also at the meetings organised by the Open Source Brain initiative. See here for more details.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Landing.html b/Landing.html new file mode 100644 index 00000000..4cef65bc --- /dev/null +++ b/Landing.html @@ -0,0 +1,722 @@ + + + + + + + + + + + NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

NeuroML#

+

A model description language for computational neuroscience.

+ + + +
+

NeuroML is an international, collaborative initiative to develop a language for describing detailed models of neural systems, which will serve as a standard data format for defining and exchanging descriptions of neuronal cell and network models. +NeuroML is:

+
    +
  • modular

  • +
  • standardised

  • +
  • structured

  • +
+

and this allows you to:

+ +

all using a well supported set of tools in the powerful Python programming language.

+

In this documentation, you will find information on using NeuroML, developing with NeuroML, its specification, and the community that maintains it.

+

For any queries, please contact the NeuroML community using any of our communication channels.

+
+
+
+
+
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/Board.html b/NeuroMLOrg/Board.html new file mode 100644 index 00000000..c7d274aa --- /dev/null +++ b/NeuroMLOrg/Board.html @@ -0,0 +1,778 @@ + + + + + + + + + + + NeuroML Editorial Board — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML Editorial Board

+ +
+ +
+
+ + + + +
+ +
+

NeuroML Editorial Board#

+

An elected board of editors has been formed to manage the NeuroML specification development process. +The editorial board consists of five members, elected by the NeuroML community. +The editors are responsible for producing and maintaining the official documentation for the NeuroML language, and work in collaboration with the Scientific Committee who provide oversight and guidance.

+

Due to the close link between the development of NeuroML 2 and LEMS, this group is also responsible for producing a stable specification for the subset of LEMS used by NeuroML 2.

+
+

Current Editorial Board#

+

The five current members of the NeuroML Editorial Board are:

+
    +
  • Salvador Dura-Bernal

  • +
  • Padraig Gleeson

  • +
  • Boris Marin

  • +
  • Ankur Sinha

  • +
  • Sotirios Panagiotou

  • +
+

Padraig Gleeson, Boris Marin and Sotirios Panagiotou were elected for three year terms in 2022 (2023–2025) and Salvador Dura-Bernal and Ankur Sinha were elected for three year terms in 2021 (2022–2024).

+
+
+
+
+Sotirios Panagiotou +

Sotirios Panagiotou
+PhD candidate
+Erasmus Medical Center
+Rotterdam, Netherlands
+Website

+
+
+
+
+Salvador Dura-Bernal +

Salvador Dura-Bernal
+SUNY Downstate
+Brooklyn, USA
+Website

+
+
+
+
+Padraig Gleeson +

Padraig Gleeson
+University College London
+UK
+Website

+
+
+
+
+Boris Marin +

Boris Marin
+Universidade Federal do ABC
+Brazil
+Website

+
+
+
+
+Ankur Sinha +

Ankur Sinha
+University College London
+UK
+Website

+
+
+
+
+

Information on past editors and elections can be found here.

+
+
+

Procedures#

+

The procedures for election of the editorial board, its responsibilities, size and activities were heavily inspired by other initiatives like SBML, that have had successful editorial teams for many years. +The COMBINE initiative seeks to promote community developed standards in computational biology, and the NeuroML editorial board will work with this initiative to ensure best practices in specification preparation.

+
+
+

Responsibilities of NeuroML Editors#

+

Their main responsibilities are:

+
    +
  • Defining and documenting the procedure for specification production: scope, release frequency, update procedures, form of specification (web based or single pdf, etc.). +This should be based on some or all of the recommendations for community based standards development from the COMBINE initiative. +These procedures for specification production will have to be agreed with the Scientific Committee.

  • +
  • Preparing the core specification for the NeuroML language.

  • +
  • Testing reference implementations of NeuroML compliant applications.

  • +
  • Preparing a specification for the LEMS language. +This can be a subset of the language supported by the reference implementations in Java (jLEMS) and Python (pyLEMS), but will have to cover all of the LEMS elements required to specify the ComponentType definitions for NeuroML 2.

  • +
  • Responding to community queries about the specification.

  • +
  • Establishing a procedure for incorporating major changes into the specification (in cooperation with the Scientific Committee).

  • +
+

Participation in the editorial board will be on a volunteer basis, there is no central funding to support this work.

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/BoardHistory.html b/NeuroMLOrg/BoardHistory.html new file mode 100644 index 00000000..cab38734 --- /dev/null +++ b/NeuroMLOrg/BoardHistory.html @@ -0,0 +1,772 @@ + + + + + + + + + + + History of the NeuroML Editorial Board — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

History of the NeuroML Editorial Board#

+

This page documents the previous members of the NeuroML Board.

+
+

Initial election of editors (2013)#

+

The first election of an editorial board for NeuroML took place in May/June 2013.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists on 3rd May 2013.

  • +
  • Anyone on these lists could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The three candidates who received the highest number of votes will serve three year terms and the two with the next highest number of votes will serve two year terms.

  • +
  • Nicolas Le Novère (lenov -at- babraham.ac.uk) was the returning officer for this initial election.

  • +
+
+
+

Election of editors (2015)#

+

The second election of an editorial board for NeuroML took place in June/July 2015.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists on 18 June 2015.

  • +
  • Anyone on these lists could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The two candidates who received the highest number of votes would serve three year terms.

  • +
  • Nicolas Le Novère (lenov -at- babraham.ac.uk) was the returning officer for this election.

  • +
  • Results were announced here.

  • +
+
+
+

Election of editors (2016)#

+

The third election of an editorial board for NeuroML took place in July/August 2016.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists on 18 July 2016.

  • +
  • Anyone on these lists could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The three candidates who received the highest number of votes would serve three year terms.

  • +
  • Nicolas Le Novère (lenov -at- babraham.ac.uk) was the returning officer for this election.

  • +
+
+
+

Election of editors (2018)#

+

The fourth election of an editorial board for NeuroML took place in Nov/Dec 2018.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years.

  • +
  • Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The two candidates who received the highest number of votes would serve three year terms.

  • +
  • Salvador Dura-Bernal was elected outright on the first round of voting and Andrew Davison was elected in a run off between the two next highest placed candidates who received the same number of votes.

  • +
  • Malin Sandstrom at the INCF was the returning officer for this election.

  • +
+
+
+

Election of editors (2019)#

+

The fifth election of an editorial board for NeuroML took place in Nov/Dec 2019.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years.

  • +
  • Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The three candidates who received the highest number of votes would serve three year terms.

  • +
  • Padraig Gleeson, Boris Marin and Justas Birgiolas were nominated, and eventually all elected to serve as editors.

  • +
  • Malin Sandstrom at the INCF was the returning officer for this election.

  • +
+
+
+

Election of editors (2022)#

+

The sixth election of an editorial board for NeuroML took place in Nov/Dec 2021.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years.

  • +
  • Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The three candidates who received the highest number of votes would serve three year terms.

  • +
  • Salvador Dura-Bernal and Ankur Sinha were nominated, and eventually all elected to serve as editors.

  • +
  • Sharon Crook was the returning officer for this election.

  • +
+
+
+

Election of editors (2024)#

+

The seventh election of an editorial board for NeuroML took place in Nov/Dec 2023.

+
    +
  • The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years.

  • +
  • Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed.

  • +
  • The three candidates who received the highest number of votes would serve three year terms.

  • +
  • Padraig Gleeson, Boris Marin, Sotirios Panagiotou and Subhasis Ray were nominated. Padraig Gleeson, Boris Marin, Sotirios Panagiotou received highest votes and were elected to serve as editors.

  • +
  • Cengiz Gunay was the returning officer for this election.

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/BoardMeetingReports.html b/NeuroMLOrg/BoardMeetingReports.html new file mode 100644 index 00000000..db2cac28 --- /dev/null +++ b/NeuroMLOrg/BoardMeetingReports.html @@ -0,0 +1,741 @@ + + + + + + + + + + + Workshop and Meeting reports — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Workshop and Meeting reports

+ +
+
+ +
+
+
+ + + + +
+ +
+

Workshop and Meeting reports#

+

Information and minutes of various NeuroML meetings can be found here.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Meeting

Location

Summary

2021 NeuroML Development workshop & Editorial Board Meeting

Online at COMBINE 2021

A NeuroML development workshop was held as part of the annual COMBINE meeting in October 2021.
+More info.

2019 NeuroML Editorial Board Meeting

CNS*2019 Meeting, Barcelona

The fifth NeuroML Editorial Board Meeting took place at the CNS meeting in Barcelona, Monday 15th July, 2019.
+Minutes.

2018 NeuroML Editorial Board Meeting

Online

The fourth NeuroML Editorial Board Meeting took place via video conference on 6th July 2018 between the NeuroML Editorial Board and interested members of the community to get an update on all current NeuroML related activities.
+Minutes.

2016 NeuroML Editorial Board Meeting

Janelia Research Campus, Virginia, USA

The third NeuroML Editorial Board Meeting took place after the Collaborative Development of Data-Driven Models of Neural Systems conference held at Janelia Research Campus in Sept 2016. +More details on the main conference can be found here.
+Minutes.

2015 NeuroML Editorial Board Meeting @ OSB 2015

Alghero, Sardinia, Italy

The second NeuroML Editorial Board Meeting took place prior to the Open Source Brain 2015 meeting held in Sardinia. +More details on the main meeting can be found here.
+Minutes.

2014 NeuroML Editorial Board Meeting @ OSB 2014

Alghero, Sardinia, Italy

The first official NeuroML Editorial Board Meeting took place prior to the Open Source Brain 2014 meeting held in Sardinia. +More details on the main meeting can be found here.
+Minutes.

2013 NeuroML Meeting Development Workshop @ OSB 2013

Alghero, Sardinia, Italy

The NeuroML Development Workshop was merged into the Open Source Brain kickoff meeting in Alghero, Sardinia. +More details on this meeting can be found here. Discussions on the state of NeuroML and future developments took place during the main meeting.

2012 NeuroML Development Workshop

Informatics Forum, Edinburgh, UK

The NeuroML workshop at was combined with the BrainScaleS (previously FACETS) CodeJam meeting.
+Minutes.

2011 NeuroML Development Workshop

University College London, UK

A key outcome of third NeuroML Development Workshop was the creation of a Scientific Committee for NeuroML.
+Minutes.

2010 NeuroML Development Workshop

Arizona State University, USA

The second NeuroML Development Workshop was held in Arizona State University to plan for version 2.0 of the NeuroML model description language. +There was also a Symposium on Multiscale Approaches to Understanding Neural Plasticity held at ASU before the main meeting and a number of tutorials on software for multiscale modeling given by the meeting participants on the following day.
+Minutes.

2009 NeuroML Development Workshop

University College London, UK

The focus of the workshop was to refine the specifications for describing models of channel kinetics and the biophysical properties of cells. +Special thanks to the Wellcome Trust, the INCF, and the NSF for their generous support of this endeavour.
+Minutes.

2008 CNS Workshop

Portland, Oregon, USA

Padraig Gleeson and Sharon Crook moderated a workshop on “Interoperability of Software for Computational and Experimental Neuroscience” at the 2008 Computational Neuroscience Meeting.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/CoC.html b/NeuroMLOrg/CoC.html new file mode 100644 index 00000000..4ba0ade8 --- /dev/null +++ b/NeuroMLOrg/CoC.html @@ -0,0 +1,671 @@ + + + + + + + + + + + Code of Conduct — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Code of Conduct

+ +
+
+ +
+
+
+ + + + +
+ +
+

Code of Conduct#

+

Everyone is welcome in the NeuroML community. +We request everyone interacting on the NeuroML channels in any capacity to treat each other respectfully. +Please:

+
    +
  • act in good faith

  • +
  • be friendly, welcoming, respectful, and patient

  • +
  • be mindful and considerate

  • +
  • be open, use prefer and promote Open Science practices.

  • +
+

If you experience or become aware of behaviour that does not adhere to the Code of Conduct, please contact the moderators of the channel/event you are in.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/CommunicationChannels.html b/NeuroMLOrg/CommunicationChannels.html new file mode 100644 index 00000000..5ec76e37 --- /dev/null +++ b/NeuroMLOrg/CommunicationChannels.html @@ -0,0 +1,718 @@ + + + + + + + + + + + Getting in touch — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Getting in touch

+ +
+ +
+
+ + + + +
+ +
+

Getting in touch#

+

We’re happy to talk with users, developers and modellers about using NeuroML in their work.

+
+

Mailing list#

+

For announcements, general discussion, queries, and troubleshooting related to NeuroML please use the mailing list: https://lists.sourceforge.net/lists/listinfo/neuroml-technology.

+
+
+

Chat channels#

+

A Gitter/Matrix chat channels for queries are also available. +One can access it either via Gitter or Matrix/Element.

+ +

Please note that activity in these rooms depends on time zones and the availability of community members. +So, if you do not get a response soon, please post to the mailing list listed above or file an issue on GitHub as noted below.

+
+ +
+

Social media#

+

You can follow NeuroML related updates on Twitter at @NeuroML.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/Contributors.html b/NeuroMLOrg/Contributors.html new file mode 100644 index 00000000..c072b715 --- /dev/null +++ b/NeuroMLOrg/Contributors.html @@ -0,0 +1,803 @@ + + + + + + + + + + + NeuroML contributors — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML contributors

+ +
+
+ +
+
+
+ + + + +
+ +
+

NeuroML contributors#

+

This page lists contributors to the various NeuroML and related repositories, listed in no particular order. +It is generated periodically, most recently on 04/09/23. See also the current NeuroML Editorial Board and the Scientific Committee. +The list of repositories can be seen on the repositories page.

+ +
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/Funding.html b/NeuroMLOrg/Funding.html new file mode 100644 index 00000000..a829625d --- /dev/null +++ b/NeuroMLOrg/Funding.html @@ -0,0 +1,722 @@ + + + + + + + + + + + Funding and Acknowledgements — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Funding and Acknowledgements

+ +
+
+ +
+
+
+ + + + +
+ +
+

Funding and Acknowledgements#

+

The NeuroML effort has been made possible by funding from research councils in the UK, EU, and the USA.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+UK Medical Research Council + +

UK Medical Research Council

+
+UK Biotechnology and Biological Sciences Research Council + +

UK Biotechnology and Biological Sciences Research Council

+
+National Institutes of Health + +

National Institutes of Health

+
+EU Synapse Project + +

EU Synapse Project

+
+National Science Foundation + +

National Science Foundation

+
+International Neuroinformatics Coordinating Facility + +

International Neuroinformatics Coordinating Facility

+
+Wellcome + +

Wellcome

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/History.html b/NeuroMLOrg/History.html new file mode 100644 index 00000000..2c5d6c33 --- /dev/null +++ b/NeuroMLOrg/History.html @@ -0,0 +1,731 @@ + + + + + + + + + + + A brief history of NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

A brief history of NeuroML

+ +
+ +
+
+ + + + +
+ +
+

A brief history of NeuroML#

+
+

The early days#

+

The concept of NeuroML was first introduced in an article by Goddard et al. (2001) [GHH+01], following meetings at the University of Edinburgh where initial templates and an overall structure for a model description language for computational modelling in neuroscience were discussed. +The proposal extended general purpose structures for neuroscience data proposed by Gardner et al. (2001) [GKA+01].

+

At that time, the design principles for NeuroML were closely linked with a specific software architecture in which a base application loads a range of plug-ins to handle different aspects of a simulation experiment. +The simulation platform Neosim provided an implementation of this approach (Howell et al. 2003 [HCG+03]), and early NeuroML development was closely aligned to this architecture. +Fred Howell and Robert Cannon developed a software library, the NeuroML Development Kit (NDK), to simplify the process of working with XML serializations of models. +This library implemented a particular dialect of XML but did not define particular structures at the model description level. +Instead, Neosim plug-in developers were free to develop their own structures and serialize them via the NDK, in the hope that some consensus would emerge around the most useful ones.

+

In practice, few developers beyond the Edinburgh group developed or used such structures and the resulting XML was too application specific to gain wider adoption. +The Neosim project was completed in 2005.

+
+
+

NeuroML v1.x#

+

Based on discussions with Howell and Cannon about the need to develop a consensus for describing widely used model components, Sharon Crook worked with the neuroanatomy community on a language for describing neuronal morphologies in XML, MorphML (Qi and Crook 2004 [QC04]). +At the same time, Padraig Gleeson, working with Angus Silver, was developing neuroConstruct, for generating neuronal simulations for the NEURON and GENESIS simulators (Gleeson et al. 2007 [GSS07]), which had its own internal simulator independent representation for morphologies, channel and networks.

+

It was agreed that these efforts should be merged under the banner of NeuroML, and the v1.x structure of NeuroML was created. +A modular approach containing MorphML, ChannelML and NetworkML was adopted to allow application developers to support only those parts of the language needed by their application (Crook et al. 2007 [CGH+07], Gleeson et al. 2010 [GCC+10]). +XML schema files for this version of the standard have been available since 2006. +The motivation, structure and functionality of this version is described in detail in Gleeson et al. 2010, while the specification of the language is outlined in the Supporting Information of that publication.

+

For converting NeuroML v1 models/files to NeuroML2, users can use neuroConstruct.

+
+
+

NeuroML v2.x - introducing LEMS…#

+

NeuroML2 development was started in 2011. +The main motivation for NeuroML2 was the lack of extensibility of NeuroML v1.x; every new model type which was introduced into the language required an update to the Schema, updates to the text documentation and an implementation in each of the native formats of the target simulators. +NeuroML2 is built on the LEMS (Low Entropy Model Specification) language, which allows machine readable definitions of the cell, channel and synapse models which form the core of the language. +This increases transparency of model structure and dynamics and facilitates automatic mapping of the models to multiple simulation formats. +More details on the structure of LEMS and how it is used in NeuroML2 can be found in Cannon et al. 2014 [CGC+14] and here.

+

In parallel with development of NeuroML2 and LEMS, software libraries for reading, writing and running simulations using the languages are under active development in Java (jNeuroML) and Python (libNeuroML and pyLEMS (see Vella et al. 2014 [VCC+14]) and pyNeuroML).

+

The NeuroML specifications are developed by the NeuroML Editorial Board and overseen by its Scientific Committee. +NeuroML specifications and the associated libraries are developed on GitHub and an overview of current activities can be found here.

+
+

Recent releases of NeuroML2

+

For full details on the recent releases of NeuroML see: here.

+
+
+
+

The future#

+

NeuroMLlite is under active development, which will significantly enhance the range of network models which can be expressed (in a concise JSON based format) and run in NeuroML supporting simulators. This work will form the basis of NeuroML v3.0.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/OutreachTraining.html b/NeuroMLOrg/OutreachTraining.html new file mode 100644 index 00000000..4e2279c9 --- /dev/null +++ b/NeuroMLOrg/OutreachTraining.html @@ -0,0 +1,719 @@ + + + + + + + + + + + Outreach and training — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Outreach and training

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Outreach and training#

+

The NeuroML community has a strong record of participating in training and outreach activities. +Information on tutorials and workshops can be seen in the Events pages.

+
+

Google summer of Code#

+

The NeuroML community participates annually in the Google Summer of Code under the INCF organisation. +Projects are centred around the standardisation of published models in NeuroML to make these standardised versions available on the Open Source Brain platform and improving the NeuroML tools wherever possible.

+
+

2022#

+ +
+
+

Other past GSoC projects#

+ +
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/Repositories.html b/NeuroMLOrg/Repositories.html new file mode 100644 index 00000000..d38d10b1 --- /dev/null +++ b/NeuroMLOrg/Repositories.html @@ -0,0 +1,840 @@ + + + + + + + + + + + NeuroML repositories — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML repositories

+ +
+
+ +
+
+
+ + + + +
+ +
+

NeuroML repositories#

+

This page lists repositories related to NeuroML, listed in no particular order. +It is generated periodically, most recently on 04/09/23. A complete list of contributors can be seen here.

+

For the status of tests on standardized NeuroML models on Open Source Brain, please see this page: OpenSourceBrain/.github.

+ +
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/ScientificCommittee.html b/NeuroMLOrg/ScientificCommittee.html new file mode 100644 index 00000000..2bef850a --- /dev/null +++ b/NeuroMLOrg/ScientificCommittee.html @@ -0,0 +1,799 @@ + + + + + + + + + + + NeuroML Scientific Committee — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML Scientific Committee

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

NeuroML Scientific Committee#

+

The responsibilities of the NeuroML Scientific Committee are:

+
    +
  • To advise on the scientific focus of the NeuroML initiative; to ensure that the structure of the language is based on the latest knowledge of neuronal anatomy and physiology.

  • +
  • To agree on the technical implementation for the core specifications (in collaboration with the NeuroML Editorial Board) and to ensure that best practices are encouraged in model specification.

  • +
  • To promote NeuroML internationally, both the core specifications and the tools which support the language.

  • +
  • To define the governance structure of the NeuroML Initiative and outline a path towards a specification process with dedicated, elected editors.

  • +
  • To engage with other standardisation and databasing initiatives in the computational neuroscience and wider biology fields.

  • +
  • To review and agree on extensions to the core specifications and the scope of the initiative; to address issues the community raises regarding the direction of the initiative.

  • +
+
+

Current Members#

+
+
+
+
+Upi Bhalla +

Upi Bhalla
+NCBS
+Bangalore, India
+Website

+
+
+
+
+Avrama Blackwell +

Avrama Blackwell
+Krasnow Institute of Advanced Studies
+George Mason University, USA
+Website

+
+
+
+
+Hugo Cornells +

Hugo Cornells
+K.U. Leuven
+Belgium
+Website

+
+
+
+
+Sharon Crook +

Sharon Crook
+Arizona State University
+USA
+Website

+
+
+
+
+Andrew Davison +

Andrew Davison
+CNRS, Gif-sur-Yvette
+France
+Website

+
+
+
+
+Robert McDougal +

Robert McDougal
+Yale University
+USA
+Website

+
+
+
+
+Lyle Graham +

Lyle Graham
+Université Paris Descartes
+Paris, France
+Website

+
+
+
+
+Cengiz Gunay +

Cengiz Gunay
+Georgia Gwinnett College
+USA
+Website

+
+
+
+
+Michael Hines +

Michael Hines
+Yale University
+USA
+Website

+
+
+
+
+Angus Silver +

Angus Silver
+University College London
+London, UK
+Website

+
+
+
+
+
+
+

Past Members#

+

(Note: past members who are currently members of the NeuroML Editorial Board are not listed.)

+
    +
  • Robert Cannon

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/NeuroMLOrg/Standards.html b/NeuroMLOrg/Standards.html new file mode 100644 index 00000000..3c93d2dd --- /dev/null +++ b/NeuroMLOrg/Standards.html @@ -0,0 +1,693 @@ + + + + + + + + + + + Overview of standards in neuroscience — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Overview of standards in neuroscience

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Overview of standards in neuroscience#

+
+

NeuroML as a standard#

+

NeuroML is an INCF endorsed standard.

+

NeuroML is a COMBINE official standard.

+
+

Work in progress

+

This page is a work in progress…

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Reference/Glossary.html b/Reference/Glossary.html new file mode 100644 index 00000000..c0c86248 --- /dev/null +++ b/Reference/Glossary.html @@ -0,0 +1,664 @@ + + + + + + + + + + + Glossary — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Glossary

+ +
+
+ +
+
+
+ + + + +
+ +
+

Glossary#

+
    +
  • XML: Extensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. (Read full entry on Wikipedia)

  • +
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Reference/zBibliography.html b/Reference/zBibliography.html new file mode 100644 index 00000000..a86cf77e --- /dev/null +++ b/Reference/zBibliography.html @@ -0,0 +1,735 @@ + + + + + + + + + + + Bibliography — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Bibliography

+ +
+
+ +
+
+
+ + + + +
+ +
+

Bibliography#

+
+
+
+[BRB+16] +

Marianne J Bezaire, Ivan Raikov, Kelly Burk, Dhrumil Vyas, and Ivan Soltesz. Interneuronal mechanisms of hippocampal theta oscillations in a full-scale model of the rodent ca1 circuit. eLife, 5:e18566, dec 2016. URL: https://doi.org/10.7554/eLife.18566, doi:10.7554/eLife.18566.

+
+
+[BBC+18] +

Inga Blundell, Romain Brette, Thomas A. Cleland, Thomas G. Close, Daniel Coca, Andrew P. Davison, Sandra Diaz-Pier, Carlos Fernandez Musoles, Padraig Gleeson, Dan F. M. Goodman, Michael Hines, Michael W. Hopkins, Pramod Kumbhar, David R. Lester, Bóris Marin, Abigail Morrison, Eric Müller, Thomas Nowotny, Alexander Peyser, Dimitri Plotnikov, Paul Richmond, Andrew Rowley, Bernhard Rumpe, Marcel Stimberg, Alan B. Stokes, Adam Tomkins, Guido Trensch, Marmaduke Woodman, and Jochen Martin Eppler. Code generation in computational neuroscience: a review of tools and techniques. Frontiers in Neuroinformatics, 12:68, 2018. doi:10.3389/fninf.2018.00068.

+
+
+[CGC+14] +

Robert C. Cannon, Padraig Gleeson, Sharon Crook, Gautham Ganapathy, Boris Marin, Eugenio Piasini, and R. Angus Silver. LEMS: a language for expressing complex biological models in concise and hierarchical form and its use in underpinning NeuroML 2. Frontiers in Neuroinformatics, 2014. doi:10.3389/fninf.2014.00079.

+
+
+[CGH+07] +

Sharon Crook, Padraig Gleeson, Fred Howell, Joseph Svitak, and R. Angus Silver. MorphML: level 1 of the NeuroML standards for neuronal morphology data and model specification. Neuroinformatics, 5(2):96–104, 5 2007. doi:10.1007/s12021-007-0003-6.

+
+
+[FHA+15] +

KA Ferguson, CYL Huh, B Amilhon, S Williams, and FK Skinner. Data set of CA1 pyramidal cell recordings using an intact whole hippocampus preparation, including recordings of rebound firing (V2). May 2015. URL: https://doi.org/10.5281/zenodo.17794, doi:10.5281/zenodo.17794.

+
+
+[GKA+01] +

D. Gardner, K. H. Knuth, M. Abato, S. M. Erde, T. White, R. DeBellis, and E. P. Gardner. Common data model for neuroscience data and data model exchange. Journal of the American Medical Informatics Association, 8(1):17–33, 1 2001. doi:10.1136/jamia.2001.0080017.

+
+
+[GCM+19] +

Padraig Gleeson, Matteo Cantarelli, Boris Marin, Adrian Quintana, Matt Earnshaw, Sadra Sadeh, Eugenio Piasini, Justas Birgiolas, Robert C. Cannon, N. Alex Cayco-Gajic, Sharon Crook, Andrew P. Davison, Salvador Dura-Bernal, András Ecker, Michael L. Hines, Giovanni Idili, Frederic Lanore, Stephen D. Larson, William W. Lytton, Amitava Majumdar, Robert A. McDougal, Subhashini Sivagnanam, Sergio Solinas, Rokas Stanislovas, Sacha J. van Albada, Werner van Geit, and R. Angus Silver. Open source brain: a collaborative resource for visualizing, analyzing, simulating, and developing standardized models of neurons and circuits. Neuron, 103(3):395–411, 2019. doi:10.1016/j.neuron.2019.05.019.

+
+
+[GCC+10] +

Padraig Gleeson, Sharon Crook, Robert C. Cannon, Michael L. Hines, Guy O. Billings, Matteo Farinella, Thomas M. Morse, Andrew P. Davison, Subhasis Ray, Upinder S. Bhalla, Simon R. Barnes, Yoana D. Dimitrova, and R. Angus Silver. NeuroML: a language for describing data driven models of neurons and networks with a high degree of biological detail. PLoS Computational Biology, 6(6):e1000815, 2010. doi:10.1371/journal.pcbi.1000815.

+
+
+[GSS07] +

Padraig Gleeson, Volker Steuber, and R. Angus Silver. neuroConstruct: a tool for modeling networks of neurons in 3d space. Neuron, 54(2):219–235, 4 2007. doi:10.1016/j.neuron.2007.03.025.

+
+
+[GHH+01] +

Nigel H. Goddard, Michael Hucka, Fred Howell, Hugo Cornelis, Kavita Shankar, and David Beeman. Towards NeuroML: model description methods for collaborative modelling in neuroscience. Philosophical Transactions of the Royal Society of London. Series B: Biological Sciences, 356(1412):1209–1228, 8 2001. doi:10.1098/rstb.2001.0910.

+
+
+[HH52] +

Alan L. Hodgkin and Andrew F. Huxley. A quantitative description of membrane current and its application to conduction and excitation in nerve. The Journal of physiology, 117(4):500, 1952.

+
+
+[HCG+03] +

F. Howell, R. Cannon, N. Goddard, H. Bringmann, P. Rogister, and H. Cornelis. Linking computational neuroscience simulation tools—a pragmatic approach to component-based development. Neurocomputing, 52-54:289–294, 6 2003. doi:10.1016/s0925-2312(02)00781-6.

+
+
+[Izh07] +

Eugene M. Izhikevich. Dynamical systems in neuroscience. MIT Press, 2007.

+
+
+[Lor63] +

Edward N. Lorenz. Deterministic nonperiodic flow. Journal of Atmospheric Sciences, 20(2):130–141, 1963. doi:10.1175/1520-0469(1963)020<0130:dnf>2.0.co;2.

+
+
+[PBM04] +

Astrid A. Prinz, Dirk Bucher, and Eve Marder. Similar network activity from disparate circuit parameters. Nature Neuroscience, 7(12):1345–1352, 2004. doi:10.1038/nn1352.

+
+
+[QC04] +

Weihong Qi and Sharon Crook. Tools for neuroinformatic data exchange: an XML application for neuronal morphology data. Neurocomputing, 58-60:1091–1095, 6 2004. doi:10.1016/j.neucom.2004.01.171.

+
+
+[RAS20] +

Subhasis Ray, Zane N. Aldworth, and Mark A. Stopfer. Feedback inhibition and its control in an insect olfactory circuit. eLife, 9:e53281, 2020. URL: https://doi.org/10.7554/eLife.53281, doi:10.7554/eLife.53281.

+
+
+[RGF+11] +

Cyrille Rossant, Dan F. Goodman, Bertrand Fontaine, Jonathan Platkiewicz, Anna Magnusson, and Romain Brette. Fitting neuron models to spike trains. Frontiers in Neuroscience, 5:9, 2011. URL: https://www.frontiersin.org/article/10.3389/fnins.2011.00009, doi:10.3389/fnins.2011.00009.

+
+
+[SKNG16] +

Arfon M. Smith, Daniel S. Katz, Kyle E. Niemeyer, and FORCE11 Software Citation Working Group. Software citation principles. PeerJ Computer Science, 2:e86, 2016. URL: https://doi.org/10.7717/peerj-cs.86, doi:10.7717/peerj-cs.86.

+
+
+[VCC+14] +

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, 8:38, 2014. doi:10.3389/fninf.2014.00038.

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Conventions.html b/Userdocs/Conventions.html new file mode 100644 index 00000000..f704582f --- /dev/null +++ b/Userdocs/Conventions.html @@ -0,0 +1,744 @@ + + + + + + + + + + + Conventions — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Conventions

+ +
+ +
+
+ + + + +
+ +
+

Conventions#

+

This page documents various conventions in use in NeuroML.

+
+

Prefer underscores instead of spaces#

+

In general, please prefer underscores _ instead of spaces wherever possible, in filenames and ids.

+
+
+

Component IDs: NmlId#

+

Some Components take an id parameter of type NmlId to set an ID for them. +They can then be referred to using their IDs when constructing paths and so on.

+

IDs of type NmlId in NeuroML are strings and have certain constraints:

+
    +
  • they must start with an alphabet (either small or capital) or an underscore

  • +
  • they may include alphabets, both small and capital letters, numbers and underscores

  • +
+

IDs are also checked during validation, so if an ID does not follow these constraints, the validation will throw an error.

+
+
+

File naming#

+

When naming different NeuroML files, we suggest the following suffixes:

+
    +
  • channel.nml for NeuroML files describing ion channels, for example: Na.channel.nml

  • +
  • cell.nml for NeuroML files describing cells, for example: hh.cell.nml

  • +
  • synapse.nml for NeuroML files describing synapses, for example: AMPA.synapse.nml

  • +
  • net.nml for NeuroML files describing networks of cells, for example: excitatory.net.nml

  • +
+

For LEMS files that describe simulations of NeuroML models (“LEMS Simulation files”), we suggest that:

+
    +
  • file names start with the LEMS_ prefix,

  • +
  • file names end in xml

  • +
+

For example LEMS_HH_Simulation.xml.

+
+LEMS Simulation file and NeuroML file +
+

Fig. 60 Typical organisation for a NeuroML simulation. The main NeuroML model is specified in a file with the network (*.net.nml), which can include/point to files containing individual synapses (*.synapse.nml) or cell files (*.cell.nml). If the latter are conductance based, they may include external channel files (*.channel.nml). The main LEMS Simulation file only needs to include the network file, and tools for running simulations of the model refer to just this LEMS file. Exceptions to these conventions are frequent and simulations will run perfectly well with all the elements inside the main LEMS file, but using this scheme will maximise reusability of model elements.#

+
+
+
+
+

Neuron segments#

+

When naming segments in multi-compartmental neuron models, we suggest the following prefixes:

+
    +
  • axon_ for axonal segments

  • +
  • dend_ for dendritic segments

  • +
  • soma_ for somatic segments

  • +
+

There are 3 specific recommended names for segment groups which contain ALL of the somatic, dendritic or axonal segments

+
    +
  • axon_group for the group of all axonal segments

  • +
  • dendrite_group for the group of all dendritic segments

  • +
  • soma_group for the group of all somatic segments

  • +
+

Ideally every segment should be a member of one and only one of these groups.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/ConvertingModels.html b/Userdocs/ConvertingModels.html new file mode 100644 index 00000000..43024872 --- /dev/null +++ b/Userdocs/ConvertingModels.html @@ -0,0 +1,853 @@ + + + + + + + + + + + Converting models to NeuroML and sharing them on Open Source Brain — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Converting models to NeuroML and sharing them on Open Source Brain#

+
+

Walk throughs available

+

Look at the Walkthroughs chapter for worked examples.

+
+

The figure below is taken from the supplementary information of the Open Source Brain paper, and gives a quick overview of the steps required and tools available for converting a model to NeuroML and sharing it on the OSB platform.

+
+Schamatic of process of converting models to NeuroML +
+

Fig. 28 Procedures and tools to convert models from native formats to NeuroML and PyNN (Taken from Gleeson et al. 2019 [GCM+19])#

+
+
+
+

Step 1) Find the original model code#

+

While it should in principle be possible to create the model based only on the description in the accompanying publication, having the original code is invaluable. +The original code allows the identification of all parameters related to the model, and it is required to verify the dynamical behaviour of the NeuroML equivalent.

+

Scripts for an increasing number of published models are available on ModelDB. +ModelDB models are also published as GitHub repositories. +Forks of these are also managed in the Open Source Brain GitHub organization and indexed on Open Source Brain version 2.

+

So, the first step is to obtain the original model code and verify that this can be run to reproduce the published results.

+
+
+

Step 2) Create GitHub and OSB accounts for sharing the code#

+
+

2a) Sign up to GitHub and OSB#

+

Sign up to GitHub to be able to share the updated code publicly. Next, sign up to Open Source Brain, and adding a reference to your GitHub user account will help link between the two resources.

+
+
+

2b) Create GitHub repository#

+

Create a new GitHub repository for your new model. There are plenty of examples of repositories containing NeuroML on OSB. It’s fine to share the code under your own user account, but if you would like to host it at OpenSourceBrain, please get in contact with the OSB team.

+

Now you can commit the scripts for original version of the model to your GitHub repository. Please check what the license/redistribution conditions are for the code! Authors who have shared their code on ModelDB are generally happy for the code to be reused, but it is good to get in contact with them as a courtesy to let them know your plans with the model. They will generally be very supportive as long as the original publications are referenced, and will often have useful information on any updated versions of the model. Adding or updating a README file will be valuable for anyone who comes across the model on GitHub.

+
+
+

2c) Create OSB project#

+

Now you can create a project on OSB which will point to the GitHub repository and will be able to find any NeuroML models committed to it. You can also add a link back to the original archived version on ModelDB, and even reuse your README on GitHub as a description. For more details on this see here.

+
+
+
+

Step 3) Improve and test original model code#

+

With the original simulator code shared on GitHub, and a README updated to describe it, new users will be able to clone the repository and start using the code as shared by the authors. Some updates may be required and any changes from the original version will be recorded under the Git history visible on GitHub.

+
+

3a) Make simpler/modularised versions of original model scripts#

+

Many of the model scripts which get released on ModelDB aim to reproduce one or two of the figures from the associated publication. However, these scripts can be quite complex, and mix simulation with some analysis of the results. They don’t always provide a single, simple run of the model with standard parameters, which would be the target for a first version of the model in NeuroML.

+

Therefore it would be useful to create some additional scripts (reusing cell/channel definition files as much as possible) illustrating the baseline behaviour of the model, including:

+
    +
  • A simple script with a single cell (or one for each if multiple cells present) - applying a simple current pulse into each (e.g. example1, example2)

  • +
  • A single compartment (soma only) example with all the ion channels (ideally one where channels can easily be added/commented out) - apply current pulse (example in NEURON)

  • +
  • A passive version of multi-compartmental cell with multiple locations recorded

  • +
  • A multi-compartmental cell with multiple channels and calcium dynamics, with the channels specified in separate files

  • +
+

These will be much easier to compare to equivalents in NeuroML.

+
+
+

3b) Add OMV tests#

+ +

Once you have some scripts which illustrate (in plots/saved data) the baseline expected behaviour of your model (spiketimes, rate of firing etc.), it would be good to put some checks in place which can be run to ensure this behaviour stays consistent across changes/commits to your repository, different versions of the underlying simulator, as well as providing a target for what the NeuroML version of the model should produce.

+

The Open Source Brain Model validation framework (OMV) is designed for exactly this, allowing small scripts to be added to your repository stating what files to execute in what simulation engine and what the expected properties of generated output should be. These tests can be run on your local machine during development, but can also be easily integrated with GitHub Actions, allowing tests across multiple simulators to be run every time there is a commit to the repository (example).

+

To start using this for your project, install OMV and test running it on your local machine (omv all) on some standard examples (e.g. Hay et al.).

+

Add OMV tests for your native simulator scripts (example), e.g. test the spike times of cell when simple current pulse applied. Commit this file to GitHub, along with a GitHub Actions workflow (example), and look for runs under the Actions tab of your project on GitHub.

+

Later, you can add OMV tests too for the equivalent NeuroML versions, reusing the Model Emergent Property (*.mep) file (example), thus testing that the behaviours of the 2 versions are the same (within a certain tolerance).

+
+
+
+

4) Create a version of the model in NeuroML 2#

+
+

4a) Create a LEMS Simulation file to run the model#

+

A LEMS Simulation file is required to specify how to run a simulation of the NeuroML model, how long to run, what to plot/save etc. Create a LEMS*.xml (example) with *.net.nml (example) and *.cell.nml (example) for a cell with only a soma (don’t try to match a full multi-compartmental cell with all channels to the original version at this early stage).

+

Start off with only passive parameters (capacitance, axial resistance and 1 leak current) set; gradually add channels as in 4b) below; apply a current pulse and save soma membrane potential to file.

+

Ensure all *nml files are valid. Ensure the LEMS*.xml runs with jnml; visually compare the behaviour with original simple script from the previous section.

+

Ensure the LEMS*.xml runs with jnml -neuron, producing similar behaviour. If there is a good correspondence, add OMV tests for the NeuroML version, using the Model Emergent Property (*.mep) file from the original script’s test.

+

When ready, commit the LEMS/NeuroML code to GitHub.

+
+
+

4b) Convert channels to NeuroML#

+

Restructure/annotate/comment channel files in the original model to be as clear as possible and ideally have all use the same overall structure (e.g. see mod files here).

+

(Optional) Create a (Python) script/notebook which contains the core activation variable expressions for the channels; this can be useful to restructure/test/plot/alter units of the expressions before generating the equivalent in NeuroML (example).

+

If you are using NEURON, use pynml-modchananalysis to generate plots of the activation variables for the channels in the mod files (example1, example2).

+

Start from an existing similar example of an ion channel in NeuroML (examples1, examples2, examples3).

+

Use pynml-channelanalysis to generate similar plots for your NeuroML based channels as your mod channels; these can easily be plotted for adding to your GitHub repo as summary pages (example1, example2).

+

Create a script to load the output of mod analysis and nml analysis and compare the outputs (example).

+
+
+

4c) Compare single compartment cell with channels#

+

Ensure you have a passive soma example in NeuroML which reproduces the behaviour of an equivalent passibe version inthe original format (from steps 3a and 4a above).

+

Gradually test the cell with passive conductance and each channel individually. Plot v along with rate variables for each channel & compare how they look during current pulse (example in NEURON vs example in NeuroML and LEMS)

+

Test these in jnml first, then in Neuron with jnml -neuron.

+

When you are happy with each of the channels, try the soma with all of the channels in place, with the same channel density as present in the soma of the original cell.

+
+
+

4d) Compare multi-compartmental cell incorporating channels#

+

If the model was created in NEURON, export the 3D morphology from the original NEURON scripts using pyNeuroML (example); this will be easier if there is a hoc script with just a single cell instance as in section 1). While there is the option to use includeBiophysicalProperties=True and this will attempt to export the conductance densities on different groups, it may be better to consolidate these and add them afterwards using correctly named groups and the most efficient representation of conductance density to group relationships (example).

+
from pyneuroml.neuron import export_to_neuroml2
+..
+export_to_neuroml2("test.hoc", "test.morphonly.cell.nml", includeBiophysicalProperties=False)
+
+
+

Alternatively manually add the <channelDensity> elements to the cell file (as here).

+

You can use the tools for visualising NeuroML Models to compare how these versions look agains the originals.

+

As with the single compartment example, it’s best to start off with the passive case, i.e no active channels on the soma or dendrites, and compare that to the original code (for membrane potential at multiple locations!), and gradually add channels.

+

Many projects on OSB were originally converted from the original format (NEURON, GENESIS, etc.) to NeuroML v1 using neuroConstruct (see here for a list of these). neuroConstruct has good support for export to NeuroML v2, and this code could form the basis for your conversion. More on using neuroConstruct here and details on conversion of models to NeuroML v1 here.

+

Note: you can also export other morphologies from NeuroMorpho.org in NeuroML2 format (example) to try out different reconstructions of the same cell type with your complement of channels.

+
+
+
+

4e) (Re)optimising cell models#

+

You can use Neurotune inside pyNeuroML to re-optimise your cell models. An example is here, and a full sequence of optimising a NeuroML model against data in NWB can be found here.

+
+
+

4f) Create an equivalent network model in NeuroML#

+

Creating an equivalent of a complex network model originally built in hoc for example in NeuroML is not trivial. The guide to network building with libNeuroML here is a good place to start.

+

See also NeuroMLlite.

+
+
+

5) Access, view and run your model on OSB#

+

When you’re happy that a version of the model is behaving correctly in NeuroML, you can try visualising it on OSB.

+

See here for more details about viewing and simulating projects on OSB.

+
+
+

6) Share and collaborate#

+

There is more information on how you can disseminate and promote your model once it is on OSB in the main documentation for that platform: +https://docs.opensourcebrain.org.

+

Consider sharing parts of the model on other NeuroML supporting resources (e.g. cell and channel files on NeuroML-DB).

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/CreatingNeuroMLModels.html b/Userdocs/CreatingNeuroMLModels.html new file mode 100644 index 00000000..683a3543 --- /dev/null +++ b/Userdocs/CreatingNeuroMLModels.html @@ -0,0 +1,671 @@ + + + + + + + + + + + Creating NeuroML models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Creating NeuroML models

+ +
+
+ +
+
+
+ + + + +
+ +
+

Creating NeuroML models#

+

There are 3 main ways of developing a new model of a neuronal system in NeuroML

+

1) Reuse elements from previous NeuroML models

+

There are an increasing number of resources where you can find and analyse previously developed NeuroML models to use as the basis for a new model. See here for details.

+

2) Writing models from scratch using Python NeuroML tools

+

The toolchain around NeuroML means that it is possible to create a model in NeuroML format from the start. Please see the Getting Started with NeuroML section for quick examples on how you can use pyNeuroML to create NeuroML models and run them.

+

3) Convert a published model developed in a simulator specific format to NeuroML

+

Most computational models used in publications are released in the particular format used by the authors during their research, often in a general purpose simulator like NEURON. Many of these can be found on ModelDB. Converting one of these to NeuroML format will mean that all further developments/modifications of the model will be standards compliant, and will give access to all of the NeuroML compliant tools for visualising/analysing/optimising/sharing the model, as well as providing multiple options for executing the model across multiple simulators.

+

The next page is a step by step guide to creating a new NeuroML model based on an existing published model, verifying its behaviour, and sharing it with the community on the Open Source Brain platform.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/ExtendingNeuroMLv2.html b/Userdocs/ExtendingNeuroMLv2.html new file mode 100644 index 00000000..2daedf0c --- /dev/null +++ b/Userdocs/ExtendingNeuroMLv2.html @@ -0,0 +1,1010 @@ + + + + + + + + + + + Extending NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Extending NeuroML#

+

As a language, LEMS defines a set of built-in types which can be used together to build more user-defined types. +For example, Python defines int, float, str and so on as built-in types, and these can then be combined to define user defined types, classes. +An object of a particular class/type can be instantiated by supplying values for the members defined in the class/type.

+

ComponentTypes in LEMS are similar to classes in Python. +They define the membership structure of the type, but they do not specify values for their members. +Once a ComponentType has been defined, an instance of it can be created by setting values for its members. +This object is referred to as a Component in LEMS.

+

Having definitions in LEMS allows their re-use, and all new ComponentTypes can be submitted for inclusion to the NeuroMLv2 specification to be made accessible to other users.

+
    +
  • Like NeuroML, LEMS also has a well defined schema (XSD) that is used to validate LEMS XML files.

  • +
  • Also similar to NeuroML, you can use the LEMS Python tools to work with LEMS and do not need to work directly with the XML files.

  • +
+

The NeuroML2 standard is a list of curated LEMS ComponentTypes. +In cases where the set of ComponentTypes defined in the NeuroML standard is not sufficient for a particular modelling project, new ComponentTypes can be defined to extend the NeuroMLv2 standard.

+
+

Creating new ComponentTypes with existing NeuroML ComponentTypes#

+

Existing ComponentTypes defined in the NeuroMLv2 standard, when sufficient, should be used to create new ComponentTypes. +These new ComponentTypes, since they consist of NeuroMLv2 ComponentTypes, will be valid against the NeuroMLv2 schema (must use a <neuroml ..> root element). +For convenience, the NeuroMLv2 schema includes a subset of the LEMS elements.

+

An example of this type of extension of NeuroML can be see here where a new Calcium dependent ion channel Component requires a new ComponentType Ca_LVAst_m_tau_tau that implements the time course of the gate.

+

However, please note that while the ComponentType will be valid NeuroML, the new Components (instances) one creates of this ComponentType (and models where Components are referenced/used) will not—since the NeuroML schema does not know of the new ComponentType. +The new Components (and the models) will be valid LEMS. +For this reason, while the ComponentType file will use a <neuroml ..> root tag, the file containing its instantiated Components will use the <Lems ..> root tag.

+
+
+

Creating new ComponentTypes with LEMS elements#

+

When ComponentTypes from the NeuroMLv2 standard are not sufficient for the creation of new ComponentTypes, one must use LEMS elements to do so. +The definitions of the NeuroMLv2 standard core ComponentTypes are examples of this.

+
+

LEMS elements#

+

The list of built-in types provided by LEMS can be seen in the LEMS documentation. +As the documentation notes, a ComponentType is the “Root element for defining component types”. +It must contain a name, and can extend another ComponentType, thus inheriting its members/attributes. +Each ComponentType can contain members of other LEMS types: Parameter, DerivedParameter, Dynamics, Exposure and so on.

+
+
+

Example: Lorenz model for cellular convection#

+

To see how to create new ComponentTypes using LEMS, let us create one that is not neuroscience specific. +We will first create it using the plain XML and then see how it can be done using the Python pyLEMS API.

+

For this example, we will use the Lorenz model for cellular convection [Lor63]. +The Wikipedia article provides a short summary of the model, and the equations that govern it:

+
+(1)#\[\begin{align} +\frac{dx}{dt} &= \sigma (y - x) \\ +\frac{dy}{dt} &= x (\rho - z) - y \\ +\frac{dz}{dt} &= xy - \beta z +\end{align}\]
+

So we can see here that we have three parameters:

+
    +
  • \(\sigma\)

  • +
  • \(\rho\)

  • +
  • \(\beta\)

  • +
+

Next, x, y, and z are the state variables for this model, with initial values x0, y0, and z0 respectively. +We also want to be able to observe the values of x, y, and z, so they must be exposed in the LEMS definition.

+

Let us start with the XML definition of a ComponentType that will describe this model. +Each XML file must start with a <Lems> “root node”. +This includes information about the version of the LEMS schema that this document is valid against. +In this case, we document that this LEMS file should be valid against version 0.7.6 of the LEMS schema.

+
<Lems xmlns="http://www.neuroml.org/lems/0.7.6"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://www.neuroml.org/lems/0.7.6 https://raw.github.com/LEMS/LEMS/master/Schemas/LEMS/LEMS_v0.7.6.xsd">
+
+      <ComponentType name="lorenz1963" description="The Lorenz system is a simplified model for atomspheric convection, derived from the Navier Stokes equations.">
+
+        <!-- Parameters: free parameters to be used in the model -->
+        <Parameter name="sigma" dimension="none" description="Prandtl Number"/>
+        <Parameter name="beta" dimension="none" description="Also named b elsewhere"/>
+        <Parameter name="rho" dimension="none" description="Related to the Rayleigh number, also named r elsewhere"/>
+
+        <!-- Initial Conditions: also free parameters to be set when creating a Component from the ComponentType -->
+        <Parameter name="x0" dimension="none"/>
+        <Parameter name="y0" dimension="none"/>
+        <Parameter name="z0" dimension="none"/>
+
+
+        <!-- Exposure: what we want to be able to record from the LEMS simulation -->
+        <Exposure name="x" dimension="none"/>
+        <Exposure name="y" dimension="none"/>
+        <Exposure name="z" dimension="none"/>
+      </ComponentType>
+</Lems>
+
+
+

Note that each parameter has a dimension, not a unit. +This is because LEMS allows us to use any valid units for each dimension, and takes care of the conversion factors and so on. +NeuroML also takes advantage of this LEMS feature, as noted here.

+

Now, we can define the dynamics of the model, summarised in the equations above:

+
        <Dynamics>
+            <!-- State variables: linked to Exposures so that they can be accessed -->
+            <StateVariable name="x" dimension="none" exposure="x"/>
+            <StateVariable name="y" dimension="none" exposure="y"/>
+            <StateVariable name="z" dimension="none" exposure="z"/>
+
+            <!-- Equations defining the dynamics of each state variable -->
+            <TimeDerivative variable="x" value="( sigma * (y - x) ) / sec"/>
+            <TimeDerivative variable="y" value="( rho * x - y - x * z ) / sec"/>
+            <TimeDerivative variable="z" value="( x * y - beta * z) / sec"/>
+
+            <!-- Actions to take on the start of a LEMS simulation -->
+            <OnStart>
+                <StateAssignment variable="x" value="x0"/>
+                <StateAssignment variable="y" value="y0"/>
+                <StateAssignment variable="z" value="z0"/>
+            </OnStart>
+        </Dynamics>
+
+
+

Our LEMS file is almost complete. +However, notice that we have used sec in the dynamics to denote time but have not yet declared it. +We define sec as a constant whose value is defined in the ComponentType itself (and will not be set by us when instantiating a Component of this ComponentType):

+
        <Constant name="sec" dimension="time" value="1s"/>
+
+
+

Also note that while we have defined this constant, we have not yet defined the time dimension or its units. +We can do that outside the ComponentType:

+
  <Dimension name="time" t="1"/>
+  <Unit name="second" symbol="s" dimension="time" power="1"/>
+  <Unit name="milli second" symbol="ms" dimension="time" power="-3"/>
+
+
+

We have defined two units for the time dimension, with their conversion factors. +LEMS will use this information to correctly convert all dimensions as required. +The NeuroMLv2 standard defines various dimensions and their units in the schema for us to use.

+

The complete LEMS file will be this:

+
<Lems xmlns="http://www.neuroml.org/lems/0.7.6"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://www.neuroml.org/lems/0.7.6 https://raw.github.com/LEMS/LEMS/master/Schemas/LEMS/LEMS_v0.7.6.xsd">
+
+  <Dimension name="time" t="1"/>
+  <Unit name="second" symbol="s" dimension="time" power="1"/>
+  <Unit name="milli second" symbol="ms" dimension="time" power="-3"/>
+
+  <ComponentType name="lorenz1963" description="The Lorenz system is a simplified model for atomspheric convection, derived from the Navier Stokes equations.">
+
+    <!-- Parameters: free parameters to be used in the model -->
+    <Parameter name="sigma" dimension="none" description="Prandtl Number"/>
+    <Parameter name="beta" dimension="none" description="Also named b elsewhere"/>
+    <Parameter name="rho" dimension="none" description="Related to the Rayleigh number, also named r elsewhere"/>
+
+    <!-- Initial Conditions: also free parameters to be set when creating a Component from the ComponentType -->
+    <Parameter name="x0" dimension="none"/>
+    <Parameter name="y0" dimension="none"/>
+    <Parameter name="z0" dimension="none"/>
+
+
+    <!-- Exposure: what we want to be able to record from the LEMS simulation -->
+    <Exposure name="x" dimension="none"/>
+    <Exposure name="y" dimension="none"/>
+    <Exposure name="z" dimension="none"/>
+    <Constant name="sec" dimension="time" value="1s"/>
+
+    <Dynamics>
+        <!-- State variables: linked to Exposures so that they can be accessed -->
+        <StateVariable name="x" dimension="none" exposure="x"/>
+        <StateVariable name="y" dimension="none" exposure="y"/>
+        <StateVariable name="z" dimension="none" exposure="z"/>
+
+        <!-- Equations defining the dynamics of each state variable -->
+        <TimeDerivative variable="x" value="( sigma * (y - x) ) / sec"/>
+        <TimeDerivative variable="y" value="( rho * x - y - x * z ) / sec"/>
+        <TimeDerivative variable="z" value="( x * y - beta * z) / sec"/>
+
+        <!-- Actions to take on the start of a LEMS simulation -->
+        <OnStart>
+            <StateAssignment variable="x" value="x0"/>
+            <StateAssignment variable="y" value="y0"/>
+            <StateAssignment variable="z" value="z0"/>
+        </OnStart>
+    </Dynamics>
+  </ComponentType>
+</Lems>
+
+
+

We now have a complete LEMS model declaration. +To use this model, we need to create an instance of the ComponentType, a Component. +This requires us to set the values of various parameters of the defined model:

+
<lorenz1963 id="lorenzCell" sigma="10" beta="2.67" rho="28"
+    x0="1.0" y0="1.0" z0="1.0"/>
+
+
+

Here, we’ve set parameters that result in the chaotic attractor regime. +We could also use different values for the parameters—like a class can have many many objects with different parameters, a ComponentType can have also have different Components.

+

Note that one can also define a Component using the standard constructor form:

+
  <Component id="lorenzCell" type="lorenz1963" sigma="10" beta="2.67" rho="28" x0="1.0" y0="1.0" z0="1.0"/>
+
+
+

The two forms are equivalent. +As with other conventions, either form can be used as long as it is used consistently.

+

The Include element type allows us to modularise our models. +In NeuroML based models, we use it to break our model down into small independent reusable files.

+
+
+

Writing the model in Python using PyLEMS#

+

While the underlying format for NeuroML and LEMS is XML, Python is the suggested programming language for end users. +In this section we will see how the Lorenz model can be written using the PyLEMS Python LEMS API. +The complete script is below:

+
#!/usr/bin/env python3
+
+import lems.api as lems
+from lems.base.util import validate_lems
+
+model = lems.Model()
+
+model.add(lems.Dimension(name="time", t=1))
+model.add(lems.Unit(name="second", symbol="s", dimension="time", power=1))
+model.add(lems.Unit(name="milli second", symbol="ms", dimension="time", power=-3))
+
+lorenz = lems.ComponentType(name="lorenz1963", description="The Lorenz system is a simplified model for atomspheric convection, derived from the Navier Stokes equations")
+model.add(lorenz)
+
+lorenz.add(lems.Parameter(name="sigma", dimension="none", description="Prandtl Number"))
+lorenz.add(lems.Parameter(name="beta", dimension="none", description="Also named b elsewhere"))
+lorenz.add(lems.Parameter(name="rho", dimension="none", description="Related to the Rayleigh number, also named r elsewhere"))
+
+
+lorenz.add(lems.Parameter(name="x0", dimension="none"))
+lorenz.add(lems.Parameter(name="y0", dimension="none"))
+lorenz.add(lems.Parameter(name="z0", dimension="none"))
+
+lorenz.add(lems.Exposure(name="x", dimension="none"))
+lorenz.add(lems.Exposure(name="y", dimension="none"))
+lorenz.add(lems.Exposure(name="z", dimension="none"))
+
+lorenz.add(lems.Constant(name="sec", value="1s", dimension="time"))
+
+lorenz.dynamics.add(lems.StateVariable(name="x", dimension="none", exposure="x"))
+lorenz.dynamics.add(lems.StateVariable(name="y", dimension="none", exposure="y"))
+lorenz.dynamics.add(lems.StateVariable(name="z", dimension="none", exposure="z"))
+
+lorenz.dynamics.add(lems.TimeDerivative(variable="x", value="( sigma * (y - x)) / sec"))
+lorenz.dynamics.add(lems.TimeDerivative(variable="y", value="( rho * x - y - x * z ) / sec"))
+lorenz.dynamics.add(lems.TimeDerivative(variable="z", value="( x * y - beta * z) / sec"))
+
+onstart = lems.OnStart()
+onstart.add(lems.StateAssignment(variable="x", value="x0"))
+onstart.add(lems.StateAssignment(variable="y", value="y0"))
+onstart.add(lems.StateAssignment(variable="z", value="z0"))
+lorenz.dynamics.add(onstart)
+
+
+model.add(lems.Component(id_="lorenzCell", type_=lorenz.name, sigma="10",
+                         beta="2.67", rho="28", x0="1.0", y0="1.0", z0="1.0"))
+
+file_name = "LEMS_lorenz.xml"
+model.export_to_file(file_name)
+
+
+validate_lems(file_name)
+
+
+

As you will see, the PyLEMS API exactly follows the XML constructs that we used before. +Running this script, let’s call it LorenzLems.py gives us:

+
$ python LorenzLems.py
+Validating LEMS_lorenz.xml against https://raw.githubusercontent.com/LEMS/LEMS/development/Schemas/LEMS/LEMS_v0.7.6.xsd
+It's valid!
+
+
+

The generated XML file is below. +As you can see, it is identical to the XML file that we wrote by hand in the previous section. +You will also see that the Python API also provides convenience functions, such as the export_to_file and validate_lems functions to quickly save your model to an XML file, and validate it.

+
<?xml version="1.0" ?>
+<Lems xmlns="http://www.neuroml.org/lems/0.7.6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/lems/0.7.6 https://raw.githubusercontent.com/LEMS/LEMS/development/Schemas/LEMS/LEMS_v0.7.6.xsd">
+  <Dimension name="time" t="1"/>
+  <Unit symbol="s" dimension="time" power="1" scale="1.0"/>
+  <Unit symbol="ms" dimension="time" power="-3" scale="1.0"/>
+  <ComponentType name="lorenz1963" description="The Lorenz system is a simplified model for atomspheric convection, derived from the Navier Stokes equations">
+    <Parameter name="sigma" dimension="none" description="Prandtl Number"/>
+    <Parameter name="beta" dimension="none" description="Also named b elsewhere"/>
+    <Parameter name="rho" dimension="none" description="Related to the Rayleigh number, also named r elsewhere"/>
+    <Parameter name="x0" dimension="none"/>
+    <Parameter name="y0" dimension="none"/>
+    <Parameter name="z0" dimension="none"/>
+    <Constant name="sec" value="1s" dimension="time"/>
+    <Exposure name="x" dimension="none"/>
+    <Exposure name="y" dimension="none"/>
+    <Exposure name="z" dimension="none"/>
+    <Dynamics>
+      <StateVariable name="x" dimension="none" exposure="x"/>
+      <StateVariable name="y" dimension="none" exposure="y"/>
+      <StateVariable name="z" dimension="none" exposure="z"/>
+      <TimeDerivative variable="x" value="( sigma * (y - x)) / sec"/>
+      <TimeDerivative variable="y" value="( rho * x - y - x * z ) / sec"/>
+      <TimeDerivative variable="z" value="( x * y - beta * z) / sec"/>
+      <OnStart>
+        <StateAssignment variable="x" value="x0"/>
+        <StateAssignment variable="y" value="y0"/>
+        <StateAssignment variable="z" value="z0"/>
+      </OnStart>
+    </Dynamics>
+  </ComponentType>
+  <Component id="lorenzCell" type="lorenz1963" sigma="10" beta="2.67" rho="28" x0="1.0" y0="1.0" z0="1.0"/>
+</Lems>
+
+
+

We strongly suggest that users use the Python tools when working with both NeuroML and LEMS. +Not only is Python easier to read and write than XML, it also provides powerful programming constructs and has a rich ecosystem of scientific software.

+
+
+
+

Examples#

+

Here are some examples of Components written using LEMS to extend NeuroML that can be used as references.

+ +
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/FAQ.html b/Userdocs/FAQ.html new file mode 100644 index 00000000..354204ca --- /dev/null +++ b/Userdocs/FAQ.html @@ -0,0 +1,698 @@ + + + + + + + + + + + Frequently asked questions (FAQ) — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Frequently asked questions (FAQ)

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Frequently asked questions (FAQ)#

+
+

Please help improve the FAQ.

+

This page lists some commonly asked questions related to NeuroML. +Please feel free to open issues to add more entries to this FAQ.

+
+
+

Are length 0 segments allowed in NeuroML?#

+

Discussion link: NeuroML/NeuroML2#115

+

There are a lot of SWC reconstructions which have adjacent points, which would get converted to zero length segments. +This shouldn’t be an issue for most visualisation applications, so no need for them to say that they can’t visualise the cell if they see it’s invalid.

+

The jnml -validate option could throw a warning when it sees these segments, but currently doesn’t (it could be added here).

+

For individual simulators, they could have an issue with this, if they map each segment to a compartment (as Moose might), but for Neuron using cables/sections with multiple segments, it shouldn’t matter as long as the section doesn’t just have one segment.

+

So ideally it should be the application which loads the NeuroML in (or the conversion/export code) which decides whether this is an issue.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/FindingNeuroMLModels.html b/Userdocs/FindingNeuroMLModels.html new file mode 100644 index 00000000..942664d3 --- /dev/null +++ b/Userdocs/FindingNeuroMLModels.html @@ -0,0 +1,754 @@ + + + + + + + + + + + Finding and sharing NeuroML models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Finding and sharing NeuroML models

+ +
+ +
+
+ + + + +
+ +
+

Finding and sharing NeuroML models#

+

There are an increasing number of repositories where you can find NeuroML models, many of which will are accepting submissions from the community who wish to share their work in this format.

+
+

NeuroML-DB: The NeuroML Database#

+
+

Read the NeuroML-DB preprint!

+

A preprint of a manuscript describing NeuroML-DB and its current features is available here.

+
+
+NeuroML Database +
+

Fig. 26 The NeuroML Database contains NeuroML files for many cells (left above), channels (right) and synapses taken from Open Source Brain, Blue Brain Project, Allen Institute and more.#

+
+
+

The NeuroML Database is a relational database that provides a means for sharing NeuroML model descriptions and their components. +One of its goals is to contribute to an efficient tool chain for model development using NeuroML. +This emphasis allows the database design and subsequent searching to take advantage of this specific format. +In particular, the NeuroML database allows for efficient searches over the components of models and metadata that are associated with a hierarchical NeuroML model description.

+

The NeuroML Database is developed and maintained by the ICON Lab at Arizona State University.

+

To submit your NeuroML model to NeuroML-DB, please see the information on this page.

+
+
+

Open Source Brain#

+
+Open Source Brain +
+

Fig. 27 Examples of NeuroML 2 models visualised on Open Source Brain. A) Hodgkin Huxley model interactive tutorial. B) Integrate and fire network model of cortical column (Potjans and Diesmann 2014), showing network connectivity. C) Cortical model with multicompartmental cells (Traub et al. 2005), showing network properties and simulated membrane potential activity. D) Model of C. elegans nervous system from OpenWorm project. All visualisation/analysis/simulation enabled due to models being in standardised NeuroML format.#

+
+
+

Open Source Brain is a platform for sharing, viewing, analysing, and simulating standardized models from different brain regions and species. +An index of various NeuroML models on Open Source Brain and their validation status can be seen here.

+

To add your NeuroML model to Open Source Brain, please see the information on this page.

+
+ +
+

NeuroMorpho.Org#

+

NeuroMorpho.Org is a database of digitally reconstructed neurons. This resource can be used to retrieve reconstructed neuronal morphologies of multiple cell types from a number of species. The database can be browsed by neuron type, brain area, species, contributing lab, or cells can be searched for according to various morphometric criteria or the associated metadata.

+

There is a utility present on the site to view the cells in 3D (based on Robert Cannon’s Cvapp), which can also save the morphologies in NeuroML 2 format.

+

A tutorial on getting data from NeuroMorpho.Org in NeuroML format can be found here.

+
+
+

OpenWorm#

+

The OpenWorm project aims to create a simulation platform to build digital in-silico living systems, starting with a C. elegans virtual organism simulation. The simulations and associated tools are being developed in a fully open source manner.

+

NeuroML is being used for the description of the 302 neurons in the worm’s nervous system, both for morphological description of the cells and their electrical properties.

+
+
+

Allen Institute#

+

Multiple cell models as produced by the Allen Institute as part of their large scale brain modelling efforts are available in NeuroML format here.

+
+
+

Blue Brain Project#

+

The detailed cortical cell models from the Blue Brain Project have been converted to NeuroML format, along with the ion channels from the Channelpedia database. See here for details.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/GettingStarted.html b/Userdocs/GettingStarted.html new file mode 100644 index 00000000..af3563e2 --- /dev/null +++ b/Userdocs/GettingStarted.html @@ -0,0 +1,716 @@ + + + + + + + + + + + Getting started with NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Getting started with NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

Getting started with NeuroML#

+

The best way to understand NeuroML is to work through NeuroML examples to see how they are constructed and what they can do. +We present below a set of step-by-step guides to illustrate how models are written and simulated using NeuroML.

+ + + + + + + +
        
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Link to guide

Description

Model life cycle stages

Guide 1

Create and simulate a simple regular spiking Izhikevich neuron in NeuroML

Create, Validate, Simulate

Guide 2

Create a network of two synaptically connected populations of Izhikevich neurons

Create, Validate, Visualise, Simulate

Guide 3

Build and simulate a single compartment Hodgkin-Huxley neuron

Create, Validate, Visualise, Simulate

Guide 4

Create and simulate a multi compartment hippocampal OLM neuron

Create, Validate, Visualise, Simulate

Guide 5

Optimise/fit NeuroML models to experimental data

Create, Validate, Simulate, Fit

Guide 6

Guide to converting cell models to NeuroML and sharing them on Open Source Brain

Create, Validate, Simulate, Share

Guide 7

Create novel NeuroML models from components on NeuroML-DB

Reuse, Create, Validate, Simulate

Guide 8

Extend NeuroML by creating a novel model type in LEMS

Create, Simulate

+

You do not need to install any software on your computers to run many of the examples above. These examples are followed by a Jupyter notebook for you to experiment with inside your browser (more info).

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/HDF5.html b/Userdocs/HDF5.html new file mode 100644 index 00000000..f63633cc --- /dev/null +++ b/Userdocs/HDF5.html @@ -0,0 +1,682 @@ + + + + + + + + + + + HDF5 support — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

HDF5 support

+ +
+
+ +
+
+
+ + + + +
+ +
+

HDF5 support#

+

The XML serializations of large NeuroML models can be prohibitive to store. +For such cases, NeuroML also includes support for saving models in the binary HDF5 format via the NeuroMLHdf5Writer in libNeuroML. The same format can be exported also from the Java API (example).

+

The format of the export is documented below:

+ +

For more details, the source code of these export functions can be seen here in the libNeuroML repository and here in org.neuroml.model.

+

HDF5 NeuroML files can be read and processed by jnml and pynml in the same way as XML files (see here for LEMS Simulation file examples which reference HDF5 NeuroML models).

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/ImportingMorphologyFiles.html b/Userdocs/ImportingMorphologyFiles.html new file mode 100644 index 00000000..7b776786 --- /dev/null +++ b/Userdocs/ImportingMorphologyFiles.html @@ -0,0 +1,805 @@ + + + + + + + + + + + Handling Morphology Files — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Handling Morphology Files

+ +
+ +
+
+ + + + +
+ +
+

Handling Morphology Files#

+

A number of formats are used in neuroscience to encode neuronal morphologies obtained from experiments involving neuronal reconstructions. +This page provides general information on these formats, and documents how they may be converted to NeuroML 2 for use in computational models.

+
+

Terminology#

+
+Morphologies in NeuroML 2. +
+

Fig. 29 Specification of morphologies in NeuroML 2. More details can be found for each element in the specification, e.g. <cell>, <morphology>, <segment>, <segmentGroup>, <proximal>, <distal>.#

+
+
+
+Figure 1 from {cite}`Crook2007` showing different representations of neuronal morphology. +
+

Fig. 30 Figure 1 from [CGH+07], a schematic comparing handling of morphological information for a simple cell by different applications. a) Schematic of biological cell structure to be represented. b) Neurolucida reconstruction where the soma is represented by an outline and three-dimensional points are specified along each branch. c) NEURON simulator format where cell structure is specified in sections. Only the center of the section is simulated unless the nseg parameter is greater than one. d) GENESIS simulator representation using compartments that are cylinders except for the soma, which can be spherical. The optimal length of each compartment is determined by the electrotonic length. e) MorphML representation (i.e. NeuroML v1) where any of the information shown in panels b through d can be encoded.#

+
+
+

All formats have their own terminology that is used to refer to different parts of the cell.

+

In NEURON:

+
    +
  • a section is an unbranched contiguous cell region

  • +
  • the morphology of a cell is defined by 3D points, pt3D

  • +
  • for simulation, one can specify how many segments a section should be divided into, given by nseg

  • +
+

In NeuroML:

+
    +
  • segments are 3D points describing the cell morphology

  • +
  • continuous, unbranched segments groups, would form a section

  • +
  • the numberInternalDivisions property can be used to set the number of divisions a segment or segment group should be divided into for simulation

  • +
+
+
+

Cell validity#

+

In general, it is usually necessary to examine NeuroML cells converted from various formats, especially experimental reconstructions, before they can be used in simulations. +This is because reconstructions may not always contain all the information necessary to simulate the cell.

+

Two potential problems that must be checked are:

+
    +
  • Point of connection of dendritic branches to the soma: e.g., in Neurolucida, there is no explicit soma but usually only an outline.

  • +
  • Zero length sections: NEURON can work with zero segment lengths (consecutive pt3d points being equal), but a standard mapping of this may not be supported in other simulators such as GENESIS.

  • +
+

An incomplete list of checks to make to ensure a valid cell is (taken from neuroConstruct):

+
    +
  • Only one segment should be without a parent (root)

  • +
  • All segments must have sections

  • +
  • All segments must have endpoints

  • +
  • All segments must have unique IDs

  • +
  • All segments must have unique names

  • +
  • All sections must have unique names

  • +
  • Segments after the first in a section must only be connected to 1 parent

  • +
  • Only one segment may be spherical and must belong to the soma_group SegmentGroup

  • +
  • The cell must have at least one segment

  • +
  • The cell must have at least one soma section, i.e., which is in the soma_group

  • +
  • The cell must have a cell name

  • +
+

The NeuroML validation tools will check for some of these and report errors where possible.

+
+
+

Formats#

+
+

NEURON#

+

There is no fixed format in NEURON for specifying morphologies. +However, cells created in NEURON may be exported to NeuroML2 format using the export_to_neuroml2 method included in pyNeuroML (example).

+
+
+

GENESIS#

+

The format for a GENESIS cell description is given here.

+
+
+

CVapp (SWC files)#

+

The SWC format was developed to cover most of the information common between Neurolucida, NEURON, and GENESIS formats. +It is used by resources such as NeuroMorpho.org.

+

Information on the SWC format can be found in the NeuroMorpho FAQ under the “What is SWC format” entry.

+

A recommended application for converting SWC into NeuroML is neuroConstruct (see below).

+
+
+

Neurolucida#

+

The Neurolucida file format is used by MicroBrightField products to store information on neuronal reconstructions. +Both binary and ASCII format files can be generated by these products. +The format allows recording of various anatomical features, not only neuronal processes such as dendrites and cell bodies, but can record other micro-anatomical features of potential interest to anatomists. +Not all of these features will be relevant when constructing a single cell computational model.

+
+
+
+

Tools#

+
+

neuroConstruct#

+

neuroConstruct includes functionality to interactively import GENESIS, NEURON, CVapp (SWC), Neurolucida, and older MorphML formats to NeuroML2. +Please see the neuroConstruct documentation for more information.

+

Conversion of neuroConstruct’s importing functions into pure Python for inclusion in pyNeuroML is a work in progress. +Please contact us if you would like to help with this task.

+
+
+

pyNeuroML#

+

pyNeuroML includes functionality to convert NEURON files into NeuroML using the export_to_neuroml2 method included in pyNeuroML (example).

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/IzhikevichNetworkExample.html b/Userdocs/IzhikevichNetworkExample.html new file mode 100644 index 00000000..69c1dee8 --- /dev/null +++ b/Userdocs/IzhikevichNetworkExample.html @@ -0,0 +1,1334 @@ + + + + + + + + + + + A two population network of regular spiking Izhikevich neurons — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

A two population network of regular spiking Izhikevich neurons

+ +
+ +
+
+ + + + +
+ +
+

A two population network of regular spiking Izhikevich neurons#

+

Now that we have defined a cell, let us see how a network of these cells may be declared and simulated. +We will create a small network of cells, simulate this network, and generate a plot of the spike times of the cells (a raster plot):

+
+Spike times of neurons recorded from the simulation +
+

Fig. 9 Spike times of neurons in 2 populations recorded from the simulation.#

+
+
+

The Python script used to create the model, simulate it, and generate this plot is below. +Please note that this example uses the NEURON simulator to simulate the model. +Please ensure that the NEURON_HOME environment variable is correctly set as noted here.

+
#!/usr/bin/env python3
+"""
+Create a simple network with two populations.
+"""
+
+import random
+import numpy as np
+
+from neuroml.utils import component_factory
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+import neuroml.writers as writers
+
+
+nml_doc = component_factory("NeuroMLDocument", id="IzNet")
+iz0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="iz2007RS0",
+    v0="-60mV",
+    C="100pF",
+    k="0.7nS_per_mV",
+    vr="-60mV",
+    vt="-40mV",
+    vpeak="35mV",
+    a="0.03per_ms",
+    b="-2nS",
+    c="-50.0mV",
+    d="100pA",
+)
+
+# Inspect the component, also show all members:
+iz0.info(True)
+
+# Create a component of type ExpOneSynapse, and add it to the document
+syn0 = nml_doc.add(
+    "ExpOneSynapse", id="syn0", gbase="65nS", erev="0mV", tau_decay="3ms"
+)
+# Check what we have so far:
+nml_doc.info(True)
+# Also try:
+print(nml_doc.summary())
+
+# create the network: turned of validation because we will add populations next
+net = nml_doc.add("Network", id="IzNet", validate=False)
+
+# create the first population
+size0 = 5
+pop0 = component_factory("Population", id="IzPop0", component=iz0.id, size=size0)
+# Set optional color property. Note: used later when generating plots
+pop0.add("Property", tag="color", value="0 0 .8")
+net.add(pop0)
+
+# create the second population
+size1 = 5
+pop1 = component_factory("Population", id="IzPop1", component=iz0.id, size=size1)
+pop1.add("Property", tag="color", value=".8 0 0")
+net.add(pop1)
+
+# network should be valid now that it contains populations
+net.validate()
+
+# create a projection from one population to another
+proj = net.add(
+    "Projection",
+    id="proj",
+    presynaptic_population=pop0.id,
+    postsynaptic_population=pop1.id,
+    synapse=syn0.id,
+)
+
+# We do two things in the loop:
+# - add pulse generator inputs to population 1 to make neurons spike
+# - create synapses between the two populations with a particular probability
+random.seed(123)
+prob_connection = 0.8
+count = 0
+for pre in range(0, size0):
+    # pulse generator as explicit stimulus
+    pg = nml_doc.add(
+        "PulseGenerator",
+        id="pg_%i" % pre,
+        delay="0ms",
+        duration="10000ms",
+        amplitude="%f nA" % (0.1 + 0.1 * random.random()),
+    )
+
+    exp_input = net.add(
+        "ExplicitInput", target="%s[%i]" % (pop0.id, pre), input=pg.id
+    )
+
+    # synapses between populations
+    for post in range(0, size1):
+        if random.random() <= prob_connection:
+            syn = proj.add(
+                "Connection",
+                id=count,
+                pre_cell_id="../%s[%i]" % (pop0.id, pre),
+                post_cell_id="../%s[%i]" % (pop1.id, post),
+            )
+            count += 1
+
+nml_doc.info(True)
+print(nml_doc.summary())
+
+# write model to file and validate
+nml_file = "izhikevich2007_network.nml"
+writers.NeuroMLWriter.write(nml_doc, nml_file)
+
+print("Written network file to: " + nml_file)
+pynml.validate_neuroml2(nml_file)
+
+# Create simulation, and record data
+simulation_id = "example_izhikevich2007network_sim"
+simulation = LEMSSimulation(
+    sim_id=simulation_id, duration=1000, dt=0.1, simulation_seed=123
+)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+simulation.create_event_output_file(
+    "pop0", "%s.0.spikes.dat" % simulation_id, format="ID_TIME"
+)
+for pre in range(0, size0):
+    simulation.add_selection_to_event_output_file(
+        "pop0", pre, "IzPop0[{}]".format(pre), "spike"
+    )
+
+simulation.create_event_output_file(
+    "pop1", "%s.1.spikes.dat" % simulation_id, format="ID_TIME"
+)
+for pre in range(0, size1):
+    simulation.add_selection_to_event_output_file(
+        "pop1", pre, "IzPop1[{}]".format(pre), "spike"
+    )
+
+lems_simulation_file = simulation.save_to_file()
+
+# Run the simulation
+pynml.run_lems_with_jneuroml_neuron(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+# Load the data from the file and plot the spike times
+# using the pynml generate_plot utility function.
+data_array_0 = np.loadtxt("%s.0.spikes.dat" % simulation_id)
+data_array_1 = np.loadtxt("%s.1.spikes.dat" % simulation_id)
+times_0 = data_array_0[:, 1]
+times_1 = data_array_1[:, 1]
+ids_0 = data_array_0[:, 0]
+ids_1 = [id + size0 for id in data_array_1[:, 0]]
+pynml.generate_plot(
+    [times_0, times_1],
+    [ids_0, ids_1],
+    "Spike times",
+    show_plot_already=False,
+    save_figure_to="%s-spikes.png" % simulation_id,
+    xaxis="time (s)",
+    yaxis="cell ID",
+    colors=["b", "r"],
+    linewidths=["0", "0"],
+    markers=[".", "."],
+)
+
+
+

As with the previous example, we will step through this script to see how the various components of the network are declared in NeuroML before running the simulation and generating the plot. +We will use the same helper functions to inspect the model as we build it: component_factory, add, info, summary.

+
+

Declaring the model in NeuroML#

+

To declare the complete network model, we must again first declare its core entities:

+
nml_doc = component_factory("NeuroMLDocument", id="IzNet")
+iz0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="iz2007RS0",
+    v0="-60mV",
+    C="100pF",
+    k="0.7nS_per_mV",
+    vr="-60mV",
+    vt="-40mV",
+    vpeak="35mV",
+    a="0.03per_ms",
+    b="-2nS",
+    c="-50.0mV",
+    d="100pA",
+)
+
+# Inspect the component, also show all members:
+iz0.info(True)
+
+# Create a component of type ExpOneSynapse, and add it to the document
+syn0 = nml_doc.add(
+    "ExpOneSynapse", id="syn0", gbase="65nS", erev="0mV", tau_decay="3ms"
+)
+
+
+

Here, we create a new document, declare the Izhikevich neuron, and also declare the synapse that we are going to use to connect one population of neurons to the other. +We use the ExpOne Synapse here, where the conductance of the synapse increases instantaneously by a constant value gbase on receiving a spike, and then decays exponentially with a decay constant tauDecay.

+

Let’s inspect our model document so far:

+
nml_doc.info(True)
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for NeuroMLDocument are:
+...
+* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)
+        * Contents ('ids'/<objects>): ['iz2007RS0']
+
+* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)
+* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)
+* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)
+* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)
+* pulse_generators (class: PulseGenerator, Optional)
+* pulse_generator_dls (class: PulseGeneratorDL, Optional)
+* id (class: NmlId, Required)
+        * Contents ('ids'/<objects>): IzNet
+
+* sine_generators (class: SineGenerator, Optional)
+...
+* IF_curr_exp (class: IF_curr_exp, Optional)
+* exp_one_synapses (class: ExpOneSynapse, Optional)
+        * Contents ('ids'/<objects>): ['syn0']
+
+* IF_cond_alpha (class: IF_cond_alpha, Optional)
+* exp_two_synapses (class: ExpTwoSynapse, Optional)
+...
+
+
+

Let’s also get a summary:

+
print(nml_doc.summary())
+*******************************************************
+* NeuroMLDocument: IzNet
+*
+*  ExpOneSynapse: ['syn0']
+*  Izhikevich2007Cell: ['iz2007RS0']
+*
+*******************************************************
+
+
+

We can now declare our network with 2 populations of these cells. +Note: setting a color as a property is optional, but is used in when we generate our plots below.

+
# create the network: turned of validation because we will add populations next
+net = nml_doc.add("Network", id="IzNet", validate=False)
+
+# create the first population
+size0 = 5
+pop0 = component_factory("Population", id="IzPop0", component=iz0.id, size=size0)
+# Set optional color property. Note: used later when generating plots
+pop0.add("Property", tag="color", value="0 0 .8")
+net.add(pop0)
+
+# create the second population
+size1 = 5
+pop1 = component_factory("Population", id="IzPop1", component=iz0.id, size=size1)
+pop1.add("Property", tag="color", value=".8 0 0")
+net.add(pop1)
+
+
+

We can test to see if the network is now valid, since we have added the required populations to it:

+
net.validate()
+
+
+

This function does not return anything if the component is valid. +If it is invalid, however, it will throw a ValueError.

+

We can now create projections between the two populations based on some probability of connection. +To do this, we iterate over each post-synaptic neuron for each pre-synaptic neuron and draw a random number between 0 and 1. +If the drawn number is less than the required probability of connection, the connection is created.

+

While we are iterating over all our pre-synaptic cells here, we also add external inputs to them using ExplicitInputs +(this could have been done in a different loop, but it is convenient to also do this here).

+
# create a projection from one population to another
+proj = net.add(
+    "Projection",
+    id="proj",
+    presynaptic_population=pop0.id,
+    postsynaptic_population=pop1.id,
+    synapse=syn0.id,
+)
+
+# We do two things in the loop:
+# - add pulse generator inputs to population 1 to make neurons spike
+# - create synapses between the two populations with a particular probability
+random.seed(123)
+prob_connection = 0.8
+count = 0
+for pre in range(0, size0):
+    # pulse generator as explicit stimulus
+    pg = nml_doc.add(
+        "PulseGenerator",
+        id="pg_%i" % pre,
+        delay="0ms",
+        duration="10000ms",
+        amplitude="%f nA" % (0.1 + 0.1 * random.random()),
+    )
+
+    exp_input = net.add(
+        "ExplicitInput", target="%s[%i]" % (pop0.id, pre), input=pg.id
+    )
+
+    # synapses between populations
+    for post in range(0, size1):
+        if random.random() <= prob_connection:
+            syn = proj.add(
+                "Connection",
+                id=count,
+                pre_cell_id="../%s[%i]" % (pop0.id, pre),
+                post_cell_id="../%s[%i]" % (pop1.id, post),
+            )
+            count += 1
+
+
+
+

Let us inspect our model again to confirm that we have it set up correctly.

+
nml_doc.info(True)
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for NeuroMLDocument are:
+* biophysical_properties (class: BiophysicalProperties, Optional)
+* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)
+* cells (class: Cell, Optional)
+* networks (class: Network, Optional)
+        * Contents ('ids'/<objects>): ['IzNet']
+
+* cell2_ca_poolses (class: Cell2CaPools, Optional)
+...
+* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)
+        * Contents ('ids'/<objects>): ['iz2007RS0']
+
+* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)
+* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)
+* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)
+* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)
+* pulse_generators (class: PulseGenerator, Optional)
+        * Contents ('ids'/<objects>): ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']
+
+* pulse_generator_dls (class: PulseGeneratorDL, Optional)
+* id (class: NmlId, Required)
+        * Contents ('ids'/<objects>): IzNet
+
+...
+* exp_one_synapses (class: ExpOneSynapse, Optional)
+        * Contents ('ids'/<objects>): ['syn0']
+
+* IF_cond_alpha (class: IF_cond_alpha, Optional)
+..
+
+
+print(nml_doc.summary())
+*******************************************************
+* NeuroMLDocument: IzNet
+*
+*  ExpOneSynapse: ['syn0']
+*  Izhikevich2007Cell: ['iz2007RS0']
+*  PulseGenerator: ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']
+*
+*  Network: IzNet
+*
+*   10 cells in 2 populations
+*     Population: IzPop0 with 5 components of type iz2007RS0
+*       Properties: color=0 0 .8;
+*     Population: IzPop1 with 5 components of type iz2007RS0
+*       Properties: color=.8 0 0;
+*
+*   20 connections in 1 projections
+*     Projection: proj from IzPop0 to IzPop1, synapse: syn0
+*       20 connections: [(Connection 0: 0 -> 0), ...]
+*
+*   0 inputs in 0 input lists
+*
+*   5 explicit inputs (outside of input lists)
+*     Explicit Input of type pg_0 to IzPop0(cell 0), destination: unspecified
+*     Explicit Input of type pg_1 to IzPop0(cell 1), destination: unspecified
+*     Explicit Input of type pg_2 to IzPop0(cell 2), destination: unspecified
+*     Explicit Input of type pg_3 to IzPop0(cell 3), destination: unspecified
+*     Explicit Input of type pg_4 to IzPop0(cell 4), destination: unspecified
+*
+*******************************************************
+
+
+
+

We can now save and validate our model.

+
# write model to file and validate
+nml_file = "izhikevich2007_network.nml"
+writers.NeuroMLWriter.write(nml_doc, nml_file)
+
+print("Written network file to: " + nml_file)
+pynml.validate_neuroml2(nml_file)
+
+
+
+

The generated NeuroML model#

+

Let us take a look at the generated NeuroML model

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="IzNet">
+    <expOneSynapse id="syn0" gbase="65nS" erev="0mV" tauDecay="3ms"/>
+    <izhikevich2007Cell id="iz2007RS0" C="100pF" v0="-60mV" k="0.7nS_per_mV" vr="-60mV" vt="-40mV" vpeak="35mV" a="0.03per_ms" b="-2nS" c="-50.0mV" d="100pA"/>
+    <pulseGenerator id="pg_0" delay="0ms" duration="10000ms" amplitude="0.105236 nA"/>
+    <pulseGenerator id="pg_1" delay="0ms" duration="10000ms" amplitude="0.153620 nA"/>
+    <pulseGenerator id="pg_2" delay="0ms" duration="10000ms" amplitude="0.124516 nA"/>
+    <pulseGenerator id="pg_3" delay="0ms" duration="10000ms" amplitude="0.131546 nA"/>
+    <pulseGenerator id="pg_4" delay="0ms" duration="10000ms" amplitude="0.102124 nA"/>
+    <network id="IzNet">
+        <population id="IzPop0" component="iz2007RS0" size="5" type="population">
+            <property tag="color" value="0 0 .8"/>
+        </population>
+        <population id="IzPop1" component="iz2007RS0" size="5" type="population">
+            <property tag="color" value=".8 0 0"/>
+        </population>
+        <projection id="proj" presynapticPopulation="IzPop0" postsynapticPopulation="IzPop1" synapse="syn0">
+            <connection id="0" preCellId="../IzPop0[0]" postCellId="../IzPop1[0]"/>
+            <connection id="1" preCellId="../IzPop0[0]" postCellId="../IzPop1[1]"/>
+            <connection id="2" preCellId="../IzPop0[0]" postCellId="../IzPop1[2]"/>
+            <connection id="3" preCellId="../IzPop0[0]" postCellId="../IzPop1[4]"/>
+            <connection id="4" preCellId="../IzPop0[1]" postCellId="../IzPop1[0]"/>
+            <connection id="5" preCellId="../IzPop0[1]" postCellId="../IzPop1[2]"/>
+            <connection id="6" preCellId="../IzPop0[1]" postCellId="../IzPop1[3]"/>
+            <connection id="7" preCellId="../IzPop0[1]" postCellId="../IzPop1[4]"/>
+            <connection id="8" preCellId="../IzPop0[2]" postCellId="../IzPop1[0]"/>
+            <connection id="9" preCellId="../IzPop0[2]" postCellId="../IzPop1[1]"/>
+            <connection id="10" preCellId="../IzPop0[2]" postCellId="../IzPop1[2]"/>
+            <connection id="11" preCellId="../IzPop0[2]" postCellId="../IzPop1[3]"/>
+            <connection id="12" preCellId="../IzPop0[2]" postCellId="../IzPop1[4]"/>
+            <connection id="13" preCellId="../IzPop0[3]" postCellId="../IzPop1[0]"/>
+            <connection id="14" preCellId="../IzPop0[3]" postCellId="../IzPop1[2]"/>
+            <connection id="15" preCellId="../IzPop0[3]" postCellId="../IzPop1[3]"/>
+            <connection id="16" preCellId="../IzPop0[3]" postCellId="../IzPop1[4]"/>
+            <connection id="17" preCellId="../IzPop0[4]" postCellId="../IzPop1[1]"/>
+            <connection id="18" preCellId="../IzPop0[4]" postCellId="../IzPop1[2]"/>
+            <connection id="19" preCellId="../IzPop0[4]" postCellId="../IzPop1[4]"/>
+        </projection>
+        <explicitInput target="IzPop0[0]" input="pg_0"/>
+        <explicitInput target="IzPop0[1]" input="pg_1"/>
+        <explicitInput target="IzPop0[2]" input="pg_2"/>
+        <explicitInput target="IzPop0[3]" input="pg_3"/>
+        <explicitInput target="IzPop0[4]" input="pg_4"/>
+    </network>
+</neuroml>
+
+
+

It should now be easy to see how the model is clearly declared in the NeuroML file. +Observe how entities are referenced in NeuroML depending on their location in the document architecture. +Here, population and projection are at the same level. +The synaptic connections using the connection tag are at the next level. +So, in the connection tags, populations are to be referred to as ../ which indicates the previous level. +The explicitinput tag is at the same level as the population and projection tags, so we do not need to use ../ here to reference them.

+

Another point worth noting here is that because we have defined a population of the same components by specifying a size rather than by individually adding components to it, we can refer to the entities of the population using the common [..] index operator.

+ +

The advantage of such a declarative format is that we can also easily get information on our model from the NeuroML file. +Similar to the summary() function that we have used so far, pyNeuroML also includes the helper pynml-summary script that can be used to get summaries of NeuroML models from their NeuroML files:

+
$ pynml-summary izhikevich2007_network.nml
+*******************************************************
+* NeuroMLDocument: IzNet
+*
+*   ExpOneSynapse: ['syn0']
+*   Izhikevich2007Cell: ['iz2007RS0']
+*   PulseGenerator: ['pulseGen_0', 'pulseGen_1', 'pulseGen_2', 'pulseGen_3', 'pulseGen_4']
+*
+*  Network: IzNet
+*
+*   10 cells in 2 populations
+*     Population: IzPop0 with 5 components of type iz2007RS0
+*     Population: IzPop1 with 5 components of type iz2007RS0
+*
+*   20 connections in 1 projections
+*     Projection: proj from IzPop0 to IzPop1, synapse: syn0
+*       20 connections: [(Connection 0: 0 -> 0), ...]
+*
+*   0 inputs in 0 input lists
+*
+*   5 explicit inputs (outside of input lists)
+*     Explicit Input of type pulseGen_0 to IzPop0(cell 0), destination: unspecified
+*     Explicit Input of type pulseGen_1 to IzPop0(cell 1), destination: unspecified
+*     Explicit Input of type pulseGen_2 to IzPop0(cell 2), destination: unspecified
+*     Explicit Input of type pulseGen_3 to IzPop0(cell 3), destination: unspecified
+*     Explicit Input of type pulseGen_4 to IzPop0(cell 4), destination: unspecified
+*
+*******************************************************
+
+
+ +

We can also generate a graphical summary of our model using pynml from pyNeuroML:

+
$ pynml izhikevich2007_network.nml -graph 3
+
+
+

This generates the following model summary diagram:

+
+Model summary graph generated using pynml and the dot tool. +
+

Fig. 10 A summary graph of the model generated using pynml and the dot tool.#

+
+
+

Other options for pynml produce other views, e.g individual connections:

+
$ pynml izhikevich2007_network.nml -graph -1
+
+
+
+Model summary graph showing individual connections between cells in the populations. +
+

Fig. 11 Model summary graph showing individual connections between cells in the populations.#

+
+
+

In our very simple network here, neurons do not have morphologies and are not distributed in space. +In later examples, however, we will also see how summary figures of the network that show the morphologies, locations of different layers and neurons, and so on can also be generated using the NeuroML tools.

+
+
+
+

Simulating the model#

+

Now that we have our model set up, we can proceed to simulating it. +We create our simulation, and setup the information we want to record from it.

+
# Create simulation, and record data
+simulation_id = "example_izhikevich2007network_sim"
+simulation = LEMSSimulation(
+    sim_id=simulation_id, duration=1000, dt=0.1, simulation_seed=123
+)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+simulation.create_event_output_file(
+    "pop0", "%s.0.spikes.dat" % simulation_id, format="ID_TIME"
+)
+for pre in range(0, size0):
+    simulation.add_selection_to_event_output_file(
+        "pop0", pre, "IzPop0[{}]".format(pre), "spike"
+    )
+
+simulation.create_event_output_file(
+    "pop1", "%s.1.spikes.dat" % simulation_id, format="ID_TIME"
+)
+for pre in range(0, size1):
+    simulation.add_selection_to_event_output_file(
+        "pop1", pre, "IzPop1[{}]".format(pre), "spike"
+    )
+
+lems_simulation_file = simulation.save_to_file()
+
+
+
+

The generated LEMS file is here:

+
<Lems>
+
+    <!-- 
+
+        This LEMS file has been automatically generated using PyNeuroML v1.1.13 (libNeuroML v0.5.8)
+
+     -->
+
+    <!-- Specify which component to run -->
+    <Target component="example_izhikevich2007network_sim"/>
+
+    <!-- Include core NeuroML2 ComponentType definitions -->
+    <Include file="Cells.xml"/>
+    <Include file="Networks.xml"/>
+    <Include file="Simulation.xml"/>
+
+    <Include file="izhikevich2007_network.nml"/>
+
+    <Simulation id="example_izhikevich2007network_sim" length="1000ms" step="0.1ms" target="IzNet" seed="123">  <!-- Note seed: ensures same random numbers used every run -->
+        <EventOutputFile id="pop0" fileName="example_izhikevich2007network_sim.0.spikes.dat" format="ID_TIME">
+            <EventSelection id="0" select="IzPop0[0]" eventPort="spike"/>
+            <EventSelection id="1" select="IzPop0[1]" eventPort="spike"/>
+            <EventSelection id="2" select="IzPop0[2]" eventPort="spike"/>
+            <EventSelection id="3" select="IzPop0[3]" eventPort="spike"/>
+            <EventSelection id="4" select="IzPop0[4]" eventPort="spike"/>
+        </EventOutputFile>
+
+        <EventOutputFile id="pop1" fileName="example_izhikevich2007network_sim.1.spikes.dat" format="ID_TIME">
+            <EventSelection id="0" select="IzPop1[0]" eventPort="spike"/>
+            <EventSelection id="1" select="IzPop1[1]" eventPort="spike"/>
+            <EventSelection id="2" select="IzPop1[2]" eventPort="spike"/>
+            <EventSelection id="3" select="IzPop1[3]" eventPort="spike"/>
+            <EventSelection id="4" select="IzPop1[4]" eventPort="spike"/>
+        </EventOutputFile>
+
+    </Simulation>
+
+</Lems>
+
+
+ +

Where we had generated a graphical summary of the model before, we can now also generate graphical summaries of the simulation using pynml and the -lems-graph option. This dives deeper into the LEMS definition of the cells, showing more of the underlying dynamics of the components:

+
$ pynml LEMS_example_izhikevich2007network_sim.xml -lems-graph
+
+
+

Here is the generated summary graph:

+
+Model summary graph generated using pynml. +
+

Fig. 12 A summary graph of the model generated using pynml -lems-graph.#

+
+
+

It shows a top-down breakdown of the simulation: from the network, to the populations, to the cell types, leading up to the components that these cells are made of (more on Components later). +Let us add the necessary code to run our simulation, this time using the well known NEURON simulator:

+
# Run the simulation
+pynml.run_lems_with_jneuroml_neuron(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+
+
+
+

Plotting recorded spike times#

+

To analyse the outputs from the simulation, we can again plot the information we recorded. +In the previous example, we had recorded and plotted the membrane potentials from our cell. +Here, we have recorded the spike times. +So let us plot them to generate our figure:

+
# Load the data from the file and plot the spike times
+# using the pynml generate_plot utility function.
+data_array_0 = np.loadtxt("%s.0.spikes.dat" % simulation_id)
+data_array_1 = np.loadtxt("%s.1.spikes.dat" % simulation_id)
+times_0 = data_array_0[:, 1]
+times_1 = data_array_1[:, 1]
+ids_0 = data_array_0[:, 0]
+ids_1 = [id + size0 for id in data_array_1[:, 0]]
+pynml.generate_plot(
+    [times_0, times_1],
+    [ids_0, ids_1],
+    "Spike times",
+    show_plot_already=False,
+    save_figure_to="%s-spikes.png" % simulation_id,
+    xaxis="time (s)",
+    yaxis="cell ID",
+    colors=["b", "r"],
+    linewidths=["0", "0"],
+    markers=[".", "."],
+)
+
+
+

Observe how we are using the same generate_plot utility function as before: it is general enough to plot different recorded quantities. +Under the hood, it passes this information to Python’s Matplotlib library. This produces the raster plot shown at the top of the page.

+

This concludes our second example. +Here, we have seen how to create, simulate, and record from a simple two population network of single compartment point neurons. +The next section is an interactive notebook that you can use to play with this example. +After that we will move on to the next example: a neuron model using Hodgkin Huxley style ion channels.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS.html b/Userdocs/LEMS.html new file mode 100644 index 00000000..53ee0dfa --- /dev/null +++ b/Userdocs/LEMS.html @@ -0,0 +1,781 @@ + + + + + + + + + + + LEMS: Low Entropy Model Specification — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

LEMS: Low Entropy Model Specification

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

LEMS: Low Entropy Model Specification#

+

A language for specifying hierarchical models based on fundamental physical relationships

+ +

LEMS is being developed to provide a compact, minimally redundant, human-readable, human-writable, declarative way of expressing models of biological systems.

+

It differs from other systems such as CellML or SBML in its requirement to be human writable and the inclusion of basic physical concepts such as dimensionality and physical nesting as part of the language. +The main goal is to enable model developers to write declarative models in LEMS in much the same way as software developers write software applications in computer languages such as in C, Java or Python. +The examples shown here use XML for expressing models as text, but LEMS is not primarily an XML language. Rather it defines a set of structures for representing models. The reference implementation also supports a more concise indentation-based format for representing models.

+

There are two independent implementations of LEMS: jLEMS, written in Java and pyLEMS written in Python. +Both are hosted on the github.com/LEMS.

+
+

Capabilities#

+

You can define ComponentTypes (e.g. a “HH channel” or “a bi-exponential synapse”) which express the general properties of a particular type of thing that goes in a model. +This includes saying what parameters they have, what child elements they are allowed, and how they behave (the equations).

+

You can then define Components based on these types by supplying values for the parameters and adding any child elements that are required, so, for example, a bi-exponential synapse model with rise time 1ms and decay 5ms would be a component.

+

ComponentTypes can extend other ComponentTypes to add extra parameters, fix certain values, and otherwise modify their behavior. +Components can extend other Components to reuse specified parameter values. +There is also a loose notion of abstract types, so a component can accept children with a particular lineage without needing to know exactly what type they are. +This can be used, for example, to define cells that accept synaptic connections provided they have a particular signature.

+

Each ComponentType can have a Dynamics element that specifies how it behaves: what the state variables are, the equations that govern them, and what happens when events are sent or received. +The interpreter takes a model consisting of type and component elements referenced from a network, builds an instance from them and runs it.

+

For those familiar with object oriented languages, the ComponentType/Component distinction is close to the normal Class/Instance distinction. +When the model is run, the same pattern applies again, with the Components acting as class definitions, with their “instances” actually containing the state variables in the running mode.

+
+
+

Background#

+

The March 2010 NeuroML meeting (minutes) identified a need to extend the capability within NeuroML for expressing a range of models of synapses. +It was decided that the hitherto adopted approach of defining parameterized building blocks to construct models by combining blocks and setting parameters was unlikely to be flexible enough to cope with the needs for synapse models. +This is not obvious a-priori, since, for example, the pre NeuroML 2.0 ion channel building blocks are fully adequate to describe the dynamics of a wide range existing channel models. +But there appears to be no such commonality in models used for synapses, where the mechanisms used range from highly detailed biochemical models to much more abstract ones.

+

This work also has antecedents in Catacomb 3, which was essentially a GUI for a component definition system and model builder using a type system similar to that proposed here. +Much of the XML processing code used in the interpreter was taken from PSICS which itself currently uses the “building block” approach to model specification. +The need for user-defined types has been considered with respect to future PSICS development, and this proposal also reflects potential requirements for PSICS.

+
+
+

Example#

+

Here is the XML for a simple integrate-and-fire cell definition:

+
 <ComponentType name="refractiaf">
+     <Parameter name="threshold" dimension="voltage"/>
+     <Parameter name="refractoryPeriod" dimension="time"/>
+     <Parameter name="capacitance" dimension="capacitance"/>
+     <Parameter name="vleak" dimension="voltage"/>
+     <Parameter name="gleak" dimension="conductance"/>
+
+     <Parameter name="current" dimension="current"/>
+     <Parameter name="vreset" dimension="voltage"/>
+     <Parameter name="deltaV" dimension="voltage"/>
+     <Parameter name="v0" dimension="voltage"/>
+
+     <EventPort name="out" direction="out"/>
+     <EventPort name="in" direction="in"/>
+
+     <Exposure name="v" dimension="voltage"/>
+
+     <Dynamics>
+         <StateVariable name="v" exposure="v" dimension="voltage" />   
+         <StateVariable name="tin" dimension="time"/>
+         <OnStart>
+             <StateAssignment variable="v" value="v0"/>
+         </OnStart>
+
+         <Regime name="refr">
+             <OnEntry>
+                 <StateAssignment variable="tin" value="t" />
+                 <StateAssignment variable="v" value="vreset" />
+             </OnEntry>
+             <OnCondition test="t .gt. tin + refractoryPeriod">
+                 <Transition regime="int" />
+             </OnCondition>
+         </Regime>
+
+         <Regime name="int" initial="true">
+             <TimeDerivative variable="v" value="(current + gleak * (vleak - v)) / capacitance" />
+             <OnCondition test="v .gt. threshold">
+                 <EventOut port="out" />
+                 <Transition regime="refr" />
+             </OnCondition>
+
+         </Regime>
+     </Dynamics>
+
+ </ComponentType>
+
+
+

Once this definition is available, a particular model using this structure can be specified with the following XML:

+
<refractiaf threshold="-40mV" refractoryPeriod="5ms" capacitance="1nF" vleak="-80mV" gleak="100pS" vreset="-70mV" v0="-70mV" deltaV="10mV" />
+
+
+

More complex models will have nested components and other types of parameters, but the basic principle of separating out the equations and parameters for reusable model components, such that the equations are only stated once, remains the same.

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample1.html b/Userdocs/LEMSExample1.html new file mode 100644 index 00000000..2b02b4eb --- /dev/null +++ b/Userdocs/LEMSExample1.html @@ -0,0 +1,1258 @@ + + + + + + + + + + + Example 1: Dimensions, Units, ComponentTypes and Components — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 1: Dimensions, Units, ComponentTypes and Components

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 1: Dimensions, Units, ComponentTypes and Components#

+

This page is structured as a walk-through of a single example explaining the various elements as they occur.

+
<Lems>
+
+    <Target component="sim1" />
+
+    <Dimension name="voltage" m="1" l="2" t="-3" i="-1" />
+    <Dimension name="time" t="1" />
+    <Dimension name="per_time" t="-1" />
+    <Dimension name="conductance" m="-1" l="-2" t="3" i="2" />
+    <Dimension name="capacitance" m="-1" l="-2" t="4" i="2" />
+    <Dimension name="current" i="1" />
+
+
+    <ComponentType name="iaf1">
+        <Parameter name="threshold" dimension="voltage" />
+        <Parameter name="refractoryPeriod" dimension="time" />
+        <Parameter name="capacitance" dimension="capacitance" />
+    </ComponentType>
+
+
+    <Unit symbol="mV" dimension="voltage" power="-3" />
+    <Unit symbol="ms" dimension="time" power="-3" />
+    <Unit symbol="pS" dimension="conductance" power="-12" />
+    <Unit symbol="nS" dimension="conductance" power="-9" />
+    <Unit symbol="uF" dimension="capacitance" power="-6" />
+    <Unit symbol="nF" dimension="capacitance" power="-9" />
+    <Unit symbol="pF" dimension="capacitance" power="-12" />
+    <Unit symbol="per_ms" dimension="per_time" power="3" />
+    <Unit symbol="pA" dimension="current" power="-12" />
+
+    <iaf1 id="celltype_a" threshold="-30 mV" refractoryPeriod="2 ms" capacitance="3uF" />
+    <!-- or -->
+    <Component id="ctb" type="iaf1" threshold="-30 mV" refractoryPeriod="2 ms" capacitance="1uF" />
+
+
+    <ComponentType name="iaf2" extends="iaf1">
+        <Fixed parameter="threshold" value="-45mV" />
+    </ComponentType>
+
+    <ComponentType name="iaf3" extends="iaf1">
+        <Parameter name="leakConductance" dimension="conductance" />
+        <Parameter name="leakReversal" dimension="voltage" />
+        <Parameter name="deltaV" dimension="voltage" />
+
+        <EventPort name="spikes-in" direction="in" />
+        <Exposure name="v" dimension="voltage" />
+
+        <Dynamics>
+            <StateVariable name="v" exposure="v" dimension="voltage" />
+            <TimeDerivative variable="v" value="leakConductance * (leakReversal - v) / capacitance" />
+
+            <OnEvent port="spikes-in">
+                <StateAssignment variable="v" value="v + deltaV" />
+            </OnEvent>
+        </Dynamics>
+
+    </ComponentType>
+
+
+    <ComponentType name="spikeGenerator">
+        <Parameter name="period" dimension="time" />
+        <EventPort name="a" direction="out" />
+        <Exposure name="tsince" dimension="time" />
+        <Dynamics>
+            <StateVariable name="tsince" exposure="tsince" dimension="time" />
+            <TimeDerivative variable="tsince" value="1" />
+            <OnCondition test="tsince .gt. period">
+                <StateAssignment variable="tsince" value="0" />
+                <EventOut port="a" />
+            </OnCondition>
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="spikeGenerator2" extends="spikeGenerator">
+        <Dynamics>
+            <StateVariable name="tlast" dimension="time" />
+            <DerivedVariable name="tsince" dimension="time" exposure="tsince" value="t - tlast" />
+            <OnCondition test="t - tlast .gt. period">
+                <StateAssignment variable="tlast" value="t" />
+                <EventOut port="a" />
+            </OnCondition>
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHRate">
+        <Parameter name="rate" dimension="per_time" />
+        <Parameter name="midpoint" dimension="voltage" />
+        <Parameter name="scale" dimension="voltage" />
+        <Requirement name="v" dimension="voltage" />
+        <Exposure name="r" dimension="per_time" />
+    </ComponentType>
+
+
+    <ComponentType name="HHExpRate" extends="HHRate">
+        <Dynamics>
+            <DerivedVariable name="r" dimension="per_time" exposure="r" value="rate * exp((v - midpoint)/scale)" />
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHSigmoidRate" extends="HHRate">
+        <Dynamics>
+            <DerivedVariable name="r" dimension="per_time" exposure="r" value="rate / (1 + exp( -(v - midpoint)/scale))" />
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHExpLinearRate" extends="HHRate">
+        <Dynamics>
+            <DerivedVariable name="x" dimension="none" value="(v - midpoint) / scale" />
+            <DerivedVariable name="r" dimension="per_time" exposure="r" value="rate * x / (1 - exp(-x))" />
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHGate0">
+        <Parameter name="power" dimension="none" />
+        <Child name="Forward" type="HHRate" />
+        <Child name="Reverse" type="HHRate" />
+        <Requirement name="v" dimension="voltage" />
+        <Exposure name="fcond" dimension="none" />
+        <Dynamics>
+            <StateVariable name="q" dimension="none" />
+            <DerivedVariable dimension="per_time" name="rf" select="Forward/r" />
+            <DerivedVariable dimension="per_time" name="rr" select="Reverse/r" />
+            <TimeDerivative variable="q" value="rf * (1 - q) - rr * q" />
+            <DerivedVariable name="fcond" dimension="none" exposure="fcond" value="q^power" />
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHGate">
+        <Parameter name="power" dimension="none" />
+        <Child name="Forward" type="HHRate" />
+        <Child name="Reverse" type="HHRate" />
+        <Requirement name="v" dimension="voltage" />
+        <Exposure name="fcond" dimension="none" />
+        <Dynamics>
+            <StateVariable name="x" dimension="none" />
+            <DerivedVariable name="ex" dimension="none" value="exp(x)" />
+            <DerivedVariable name="q" dimension="none" value="ex / (1 + ex)" />
+            <DerivedVariable name="rf" dimension="per_time" select="Forward/r" />
+            <DerivedVariable name="rr" dimension="per_time" select="Reverse/r" />
+            <TimeDerivative variable="x" value="(1 + ex)^2 / ex * (rf * (1 - q) - rr * q)" />
+            <DerivedVariable name="fcond" dimension="none" exposure="fcond" value="q^power" />
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHChannel">
+        <Parameter name="conductance" dimension="conductance" />
+        <Children name="gates" type="HHGate" />
+        <Exposure name="g" dimension="conductance" />
+        <Dynamics>
+            <DerivedVariable name="gatefeff" dimension="none"
+                             select="gates[*]/fcond" reduce="multiply" />
+            <DerivedVariable name="g" exposure="g"
+                             dimension="conductance" value="conductance * gatefeff" />
+        </Dynamics>
+    </ComponentType>
+
+
+    <HHChannel id="na" conductance="20pS">
+        <HHGate id="m" power="3">
+            <Forward type="HHExpLinearRate" rate="1.per_ms"
+                     midpoint="-40mV" scale="10mV" />
+            <Reverse type="HHExpRate" rate="4per_ms" midpoint="-65mV"
+                     scale="-18mV" />
+        </HHGate>
+        <HHGate id="h" power="1">
+            <Forward type="HHExpRate" rate="0.07per_ms"
+                     midpoint="-65.mV" scale="-20.mV" />
+            <Reverse type="HHSigmoidRate" rate="1per_ms"
+                     midpoint="-35mV" scale="10mV" />
+        </HHGate>
+    </HHChannel>
+
+
+    <HHChannel id="k" conductance="20pS">
+        <HHGate id="n" power="4">
+            <Forward type="HHExpLinearRate" rate="0.1per_ms"
+                     midpoint="-55mV" scale="10mV" />
+            <Reverse type="HHExpRate" rate="0.125per_ms"
+                     midpoint="-65mV" scale="-80mV" />
+        </HHGate>
+    </HHChannel>
+
+
+    <ComponentType name="ChannelPopulation">
+        <ComponentReference name="channel" type="HHChannel" />
+        <Parameter name="number" dimension="none" />
+        <Parameter name="erev" dimension="voltage" />
+        <Requirement name="v" dimension="voltage" />
+        <Exposure name="current" dimension="current" />
+
+        <Dynamics>
+            <DerivedVariable name="channelg" dimension="conductance" select="channel/g" />
+            <DerivedVariable name="geff" dimension="conductance" value="channelg * number" />
+            <DerivedVariable name="current" dimension="current" exposure="current" value="geff * (erev - v)" />
+        </Dynamics>
+
+        <Structure>
+            <ChildInstance component="channel" />
+        </Structure>
+    </ComponentType>
+
+
+
+    <ComponentType name="HHCell">
+        <Parameter name="capacitance" dimension="capacitance" />
+        <Children name="populations" type="ChannelPopulation" />
+        <Parameter name="injection" dimension="current" />
+        <Parameter name="v0" dimension="voltage" />
+        <Exposure name="v" dimension="voltage" />
+        <Dynamics>
+            <OnStart>
+                <StateAssignment variable="v" value="v0" />
+            </OnStart>
+
+            <DerivedVariable name="totcurrent"
+                             dimension="current" select="populations[*]/current"
+                             reduce="add" />
+            <StateVariable name="v" exposure="v"
+                           dimension="voltage" />
+            <TimeDerivative variable="v"
+                            value="(totcurrent + injection) / capacitance" />
+        </Dynamics>
+    </ComponentType>
+
+
+
+    <HHCell id="hhcell_1" capacitance="1pF" injection="4pA" v0="-60mV">
+        <ChannelPopulation channel="na" number="6000"  erev="50mV" />
+        <ChannelPopulation channel="k" number="1800" erev="-77mV" />
+    </HHCell>
+
+
+    <Component id="celltype_c" type="iaf3" leakConductance="3 pS" refractoryPeriod="3 ms" threshold="45 mV" leakReversal="-50 mV" deltaV="5mV" capacitance="1uF" />
+
+    <Component id="gen1" type="spikeGenerator" period="30ms" />
+
+    <Component id="gen2" type="spikeGenerator2" period="32ms" />
+
+    <Component id="iaf3cpt" type="iaf3" leakReversal="-50mV" deltaV="50mV" threshold="-30mV" leakConductance="50pS" refractoryPeriod="4ms" capacitance="1pF" />
+
+
+    <Include file="SimpleNetwork.xml" />
+
+
+    <Network id="net1">
+        <Population id="p1" component="gen1" size="1" />
+        <Population id="p2" component="gen2" size="1" />
+        <Population id="p3" component="iaf3cpt" size="1" />
+
+        <Population id="hhpop" component="hhcell_1" size="1" />
+
+        <EventConnectivity id="p1-p3" source="p1" target="p3">
+            <Connections type="AllAll" />
+        </EventConnectivity>
+    </Network>
+
+
+    <Include file="SingleSimulation.xml" />
+    
+    <Simulation id="sim1" length="80ms" step="0.01ms" target="net1">
+        <Display id="d0" title="Example 1: Dimensions, Units, ComponentTypes and Components" 
+                 timeScale="1ms" xmin="-10" xmax="90" ymin="-90" ymax="60">
+            <Line id="tsince" quantity="p1[0]/tsince" scale="1ms" timeScale="1ms" color="#00c000" />
+            <Line id="p3v" quantity="p3[0]/v" scale="1mV" timeScale="1ms" color="#0000f0" />
+            <Line id="p0v" quantity="hhpop[0]/v" scale="1mV" timeScale="1ms" color="#ff4040" />
+        </Display>
+    </Simulation>
+
+</Lems>
+
+
+

The whole model is wrapped in a block which, for now, is called “Lems” (Low Entropy Model Specification). Then we define the dimensions that will be used in this model. Typically these would be loaded from an external file along with various other stuff, not repeated in each model, but it is included here in the interests of having a single file for everything.

+
<Dimension name="voltage" m="1" l="2" t="3" i="-1" />
+<Dimension name="time" t="1" />
+<Dimension name="per_time" t="-1" />
+<Dimension name="conductance" m="-1" l="-2" t="3" i="2" />
+<Dimension name="capacitance" m="-1" l="-2" t="4" i="2" />
+<Dimension name="current" i="1" />
+
+
+

Each dimension element just associates a dimension name with the exponents for mass, length, time and current.

+

At this stage, one can begin defining component types. +This is done with the ComponentType element and child Parameter elements. +A simple cell model with three parameters could be defined as:

+
<ComponentType name="cell1">     
+   <Parameter name="threshold" dimension="voltage" />     
+   <Parameter name="refractoryPeriod" dimension="time" />     
+   <Parameter name="capacitance" dimension="capacitance" />    
+</ComponentType>
+
+
+

Each of the Parameter elements defines a parameter that should be supplied when a component is defined based on this type. +Before we can define a component though, we need some units to use in setting those values.

+

Defining a unit involves supplying the symbol, dimension and the power of ten by which it is scaled from the IS base unit. +Note that units have a symbol, not a name. +This is because they occur as a component of an assignment expression such as ‘threshold=“-45mV”’ not as a reference such as ‘dimension=“voltage”’. In general, where one component refers to another, then the attribute value is the name of the thing being referred to, and the attribute name is the lower case version of the type of the thing being referred to. +Thus when a dimension is declared with <Dimension name=“voltage”…/> then it is referred to from a Parameter as . This holds for all references to components of a particular type.

+

Returning to the units, this model will use the following, which normally would also be loaded from an external file of standard settings.

+
<Unit symbol="mV" dimension="voltage" powTen="-3" />
+<Unit symbol="ms" dimension="time" powTen="-3" />
+<Unit symbol="pS" dimension="conductance" powTen="-12" />
+<Unit symbol="nS" dimension="conductance" powTen="-9" />
+<Unit symbol="uF" dimension="capacitance" powTen="-6" />
+<Unit symbol="nF" dimension="capacitance" powTen="-9" />
+<Unit symbol="pF" dimension="capacitance" powTen="-12" />
+<Unit symbol="per_ms" dimension="per_time" powTen="3" />
+<Unit symbol="pA" dimension="current" powTen="-12" />
+
+
+

Once the units are available it is possible to define a component. +There are two equivalent ways of doing this: either by using the Component element and setting its type, or by using the type as a new XML element. +The latter may be a little more readable, but for a simple component like this it doesn’t make much difference. +For more complicated components with nested children though, the second form is definitely clearer (eg see the HHChannel examples later).

+
<Component id="ctb" type="cell1" threshold="-30 mV" refractoryPeriod="2 ms" capacitance="1uF" />
+<cell1 id="celltype_a" threshold="-30 mV" refractoryPeriod="2 ms" capacitance="3uF" />
+
+
+

In specifying a component, a value must be supplied for each of the parameters defined in the corresponding type. +The value is composed of a number and a unit. +It can’t include expressions with multiple units for the values so, for example, to express an acceleration you couldn’t write “3 m s^-2”. Instead would need to define a unit element for the compound unit (and a dimension element for acceleration) and use that.

+

Specifying all the parameters for each component can lead to duplication. +Suppose, for example, you want to build a range of cell models all based on cell1, but you don’t want to change the threshold. +You could define a new type without the threshold, but it is neater to still use the same type but specify that you are restricting attention to the set that all have a particular value for the threshold. +This can be done by creating a new type that extends the cell1 type and includes a Fixed element to fix the threshold:

+
<ComponentType name="cell2" extends="cell1">     
+   <Fixed parameter="threshold" value="-45mV" />
+</ComponentType>
+
+
+

The cell2 type can now be used by only setting the remaining two parameters.

+

As well as restricting types when you extend them, you can also add new parameters as shown in the next type. +This also introduces an EventPort, to indicate that instances of components built from this type can receive events, and, finally, a Dynamics block. +This is where the Dynamics of instances of the component can be specified. +The phrase “instances of the component” is intentional. +The type itself doesn’t “behave”: it is just a definition. +A component built from the type doesn’t “behave” either: it is just a set of parameter values linked back to the type. +The thing that “behaves” is an instance in a runnable model that actually contains state variables. +In general, many components may be based on one type, and one component may give rise to many instances in a running model.

+

Here is a basic capacitative cell with a leaking potential and a simple event handler.

+
<ComponentType name="cell3" extends="cell1">     
+   <Parameter name="leakConductance" dimension="conductance" />     
+   <Parameter name="leakReversal" dimension="voltage" />     
+   <Parameter name="deltaV" dimension="voltage" />     
+   <EventPort name="spikes-in" direction="in" />     
+   <Exposure name="v" dimension="voltage" />     
+   <Dynamics>        
+      <StateVariable name="v" exposure="v" dimension="voltage" />        
+      <TimeDerivative variable="v" value="leakConductance * (leakReversal - v) / capacitance" />        
+      <OnEvent port="spikes-in">             
+         <StateAssignment variable="v" value="v + deltaV" />        
+      </OnEvent>     
+   </Dynamics>
+</ComponentType>
+
+
+

The Dynamics involves a single state variable, a voltage called “v”, and one equation, expressing how v drifts towards the leak reversal potential. +The event block specifies what happens when an instance receives an event. +In this case the state variable v is bumped up by deltaV. The value attribute in the TimeDerivative element is an expression involving the parameters and the state variables. +It gives the right hand side of a first order differential equation dv/dt = (…). Expressions follow normal operator precedence rules with “^” for general powers and exp(x) for exponentials.

+

Below is another example of a Dynamics, this time with an output port and a condition testing block that sends an event when the condition becomes true. +The test attribute in the OnCondition element is a boolean valued expression. +These use Fortran style operators (.gt. and .lt. for > and <) to avoid confusion with xml angle brackets.

+
<ComponentType name="spikeGenerator">     
+   <Parameter name="period" dimension="time" />     
+   <EventPort name="a" direction="out" />     
+   <Exposure name="tsince" dimension="time" />     
+   <Dynamics>         
+      <StateVariable name="tsince" exposure="tsince" dimension="time" />         
+      <TimeDerivative variable="tsince" value="1" />         
+      <OnCondition test="tsince .gt. period">             
+         <StateAssignment variable="tsince" value="0" />             
+         <EventOut port="a" />         
+      </OnCondition>     
+   </Dynamics>
+</ComponentType>
+
+
+

The above model is one way of writing a regular event generator. +It has a state variable that grows in sync with t until it reaches a threshold when the event fires and it is reset. +The model below achieves the same effect without solving a differential equation. +Instead, it asks for access to the global time variable (“t” is the one global variable that is always available) and uses that in the test condition. +[aside - there’s a slight problem here since t exists even if the model doesn’t define a dimension called time].

+
<ComponentType name="spikeGenerator2" extends="spikeGenerator">     
+   <Dynamics>         
+      <GlobalVariable name="t" dimension="time" />         
+      <StateVariable name="tlast" dimension="time" />         
+      <DerivedVariable name="tsince" exposure="tsince" value="t - tlast" />         
+      <OnCondition test="t - tlast .gt. period">             
+         <StateAssignment variable="tlast" value="t" />             
+         <EventOut port="a" />         
+      </OnCondition>     
+   </Dynamics>
+</ComponentType>
+
+
+

The examples so far have all been of very simple components which just had a single set of parameters. +Real models however require rather more structure than this with components having children of various types and possibly multiple children of certain types. +To illustrate this, the next example shows how the concept of an ion channel using Hodgkin-Huxley Dynamics can be defined.

+

Starting from the bottom, we define the different types of rate equations that occur. +These will supply terms in the equations for the derivatives of the gating particles. +There are three different expressions used in the HH equations, but they can all be expressed with three parameters, rate, midpoint and scale. +We first define a general rate class, and then extend it for the three cases.

+

The HHRate Dynamics shows two new constructs. +An Exposure declares that the component makes a quantity available to other components. +A Requirement specifies that the component needs to know about a variable that it doesn’t define itself. +When it is used in a model, the specified variable must be available (and have the right dimension) in the parent component or one of its more remote ancestors.

+

Note that the general HHRate class defines an Exposure without a Dynamics block to actually set its value. +This is analogous to an abstract class in java: you can’t actually make a component out of the HHRate element directly (the interpreter will complain) but any component using a HHRate will know it has an exposed variable called “r”. The types that extend HHRate have to supply a value for “r” before they are fully defined and ready to be used.

+

So here is the basic HHRate and its three extensions:

+
<ComponentType name="HHRate">     
+   <Parameter name="rate" dimension="per_time" />     
+   <Parameter name="midpoint" dimension="voltage" />     
+   <Parameter name="scale" dimension="voltage" />     
+   <Exposure name="r" dimension="per_time" />    
+</ComponentType>
+<ComponentType name="HHExpRate" extends="HHRate">     
+   <Dynamics>         
+      <DerivedVariable name="r" exposure="r" value="rate * exp((v - midpoint)/scale)" />     
+   </Dynamics>
+</ComponentType>
+<ComponentType name="HHSigmoidRate" extends="HHRate">     
+   <Dynamics>         
+      <DerivedVariable name="r" exposure="r" value="rate / (1 + exp(0 - (v - midpoint)/scale))" />     
+   </Dynamics>
+</ComponentType>
+<ComponentType name="HHExpLinearRate" extends="HHRate">     
+   <Dynamics>         
+      <DerivedVariable name="x" value="(v - midpoint) / scale" />         
+      <DerivedVariable name="r" exposure="r" value="rate * x / (1 - exp(0 - x))" />     
+   </Dynamics>
+</ComponentType>
+
+
+

Now the rate elements are available, they can be used to define a component for a gate in a HH model. +This introduces the Child element which says that components built using this type must include a subcomponent of the specified type. +A HH gate needs subcomponents for the forward and reverse rates.

+
<ComponentType name="HHGate0">     
+   <Parameter name="power" dimension="none" />      
+   <Child name="Forward" type="HHRate" />     
+   <Child name="Reverse" type="HHRate" />     
+   <Exposure name="fcond" dimension="none" />     
+   <Requirement name="v" dimension="voltage" />     
+   <Dynamics>         
+      <StateVariable name="q" dimension="none" />         
+      <DerivedVariable name="rf" select="Forward/r" />         
+      <DerivedVariable name="rr" select="Reverse/r" />          
+      <TimeDerivative variable="q" value="rf * (1 - q) - rr * q" />         
+      <DerivedVariable name="fcond" exposure="fcond" value="q^power" />     
+   </Dynamics>
+</ComponentType>
+
+
+

The above is a perfectly reasonable way to define a HH gate but unfortunately it needs smarter numerics than the simple forward Euler rule used in the proof of concept interpreter. +Running this model with the Euler method leads to numerical instabilities. +Happily, this problem can be circumvented without improving the numerics by changing the state variable. +Instead of q which is defined on [0, 1] you can use x defined on (-infinity, infinity) which works much better with a naive integration scheme. +This is what it looks like with x instead of q:

+
<ComponentType name="HHGate">     
+   <Parameter name="power" dimension="none" />      
+   <Child name="Forward" type="HHRate" />     
+   <Child name="Reverse" type="HHRate" />     
+   <Exposure name="fcond" dimension="none" />     
+   <Requirement name="v" dimension="voltage" />     
+   <Dynamics>         
+      <StateVariable name="x" dimension="none" />         
+      <DerivedVariable name="ex" dimension="none" value="exp(x)" />         
+      <DerivedVariable name="q" dimension="none" value="ex / (1 + ex)" />         
+      <DerivedVariable name="rf" select="Forward/r" />         
+      <DerivedVariable name="rr" select="Reverse/r" />          
+      <TimeDerivative variable="x" value="(1 + ex)^2 / ex * (rf * (1 - q) - rr * q)" />         
+      <DerivedVariable name="fcond" exposure="fcond" value="q^power" />     
+   </Dynamics>
+</ComponentType>
+
+
+

Now the gate type has been defined, it can be used to say what a HH Channel actually is. +In this picture, a channel just has a conductance and one or more gates:

+
<ComponentType name="HHChannel">     
+   <Parameter name="conductance" dimension="conductance" />     
+   <Children name="gates" type="HHGate" min="0" max="4" />     
+   <Requirement name="v" dimension="voltage" />     
+   <Exposure name="g" dimension="conductance" />          
+   <Dynamics>                  
+      <DerivedVariable name="gatefeff" select="gates[*]/fcond" reduce="multiply" />         
+      <DerivedVariable name="g" exposure="g" value="conductance * gatefeff" />     
+   </Dynamics>
+</ComponentType>
+
+
+

This introduces one new construct, the Children element, that allows for an indeterminate number of children of a given type. +This means that the same type can be used for potassium channels with only one gate, sodium channels with two gates or indeed other channels with more gates. +The first derived variable in the Dynamics block uses a xpath-style selection function to process the indeterminate number of children. +In this case it computes the produce of the fcond variables from the different gates.

+

With these definitions in place, it is now possible to define some channel models. +The classic Hodgkin-Huxley sodium channel can be represented as:

+
<HHChannel id="na" conductance="20pS">     
+   <HHGate id="m" power="3">         
+      <Forward type="HHExpLinearRate" rate="1.per_ms" midpoint="-40mV" scale="10mV" />         
+      <Reverse type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV" />     
+   </HHGate>          
+   <HHGate id="h" power="1">         
+      <Forward type="HHExpRate" rate="0.07per_ms" midpoint="-65.mV" scale="-20.mV" />         
+      <Reverse type="HHSigmoidRate" rate="1per_ms" midpoint="-35mV" scale="10mV" />     
+   </HHGate>
+</HHChannel>
+
+
+

The potassium channel uses exactly the same types, but has only one gate:

+
<HHChannel id="k" conductance="20pS">     
+   <HHGate id="n" power="4">         
+      <Forward type="HHExpLinearRate" rate="0.1per_ms" midpoint="-55mV" scale="10mV" />         
+      <Reverse type="HHExpRate" rate="0.125per_ms" midpoint="-65mV" scale="-80mV" />     
+   </HHGate>
+</HHChannel>
+
+
+

These channel models are an example where the ability to use the type name as the XML tag makes the model much clearer: the alternative just with three levels of Component elements would look rather unhelpful.

+

Although the channel models have now been defined, they still need to be used in a cell before anything can be run. +For this we’ll just define a basic channel population type. +There is one new construct here: the ComponentRef element which in this case says that a channel population needs a reference to a component of type HHChannel. This is much like a Child element, but instead of the component being defined then and there inside the channel population, there is just a reference to it.

+

The Dynamics block for a cannel population just computes the total conductance and then the current, in this case using Ohm’s law.

+
<ComponentType name="ChannelPopulation">     
+   <ComponentRef name="channel" type="HHChannel" />     
+   <Parameter name="number" dimension="none" />     
+   <Parameter name="erev" dimension="voltage" />     
+   <Requirement name="v" dimension="voltage" />     
+   <Exposure name="current" dimension="current" />     
+   <Dynamics>         
+      <DerivedVariable name="channelg" select="channel/g" />         
+      <DerivedVariable name="geff" value="channelg * number" />         
+      <DerivedVariable name="current" exposure="current" value="geff * (erev - v)" />     
+   </Dynamics>
+</ComponentType>
+
+
+

To use these populations, they need inserting in a cell. +The following type represents a simple cell with a number of populations and an option to inject a current so it does something interesting.

+
<ComponentType name="HHCell">     
+   <Parameter name="capacitance" dimension="capacitance" />     
+   <Children name="populations" type="ChannelPopulation" />     
+   <Parameter name="injection" dimension="current" />     
+   <Parameter name="v0" dimension="voltage" />     
+   <Exposure name="v" dimension="voltage" />     
+   <Dynamics>         
+      <OnStart>              
+         <StateAssignment variable="v" value="v0" />         
+      </OnStart>             
+      <DerivedVariable name="totcurrent" select="populations[*]/current" reduce="add" />         
+      <StateVariable name="v" dimension="voltage" />          
+      <TimeDerivative variable="v" value="(totcurrent + injection) / capacitance" />     
+   </Dynamics>
+</ComponentType>
+
+
+

This Dynamics block introduces the OnStart element which is much like the OnEvent elements earlier, except the block applies only when the simulation starts. +In this case it just sets the voltage to a value supplied as a parameter. +The Dynamics block uses another selector function “sum(…” to sum the currents delivered by the various populations.

+

Now all the definitions are in place to define a cell model with a couple of channel populations:

+
<HHCell id="hhcell_1" capacitance="1pF" injection="4pA" v0="-60mV">     
+   <ChannelPopulation channel="na" number="6000" erev="50mV" />     
+   <ChannelPopulation channel="k" number="1800" erev="-77mV" />
+</HHCell>
+
+
+

To go with this cell type, we can define some components using the other types defined earlier. +Note how celltype_d is based on an existing component via the “extends” attribute and only replaces one parameter value.

+
<Component id="celltype_c" type="iaf3" leakConductance="3 pS" refractoryPeriod="3 ms" threshold="45 mV" leakReversal="-50 mV" deltaV="5mV" capacitance="1uF" />
+<Component id="celltype_d" extends="celltype_c" leakConductance="5 pS" />
+<Component id="gen1" type="spikeGenerator" period="30ms" />
+<Component id="gen2" type="spikeGenerator2" period="32ms" />
+<Component id="cell3cpt" type="cell3" leakReversal="-50mV" deltaV="50mV" threshold="-30mV" leakConductance="50pS" refractoryPeriod="4ms" capacitance="1pF" />
+
+
+

Finally a simulation element says what component is to be run and for how long. +It also contains an embedded display element so the results of the simulation can be visualized. +These are also user-defined types: their definitions will be presented in example 6.

+
<Simulation length="80ms" step="0.05ms" target="hhcell_1">     
+   <Display unit="ms">         
+      <Line quantity="v" unit="mV" color="#0000f0" />     
+   </Display>
+</Simulation>
+
+
+

That’s it. When this model is run it produces the figure shown below (after rescaling a bit).

+
+LEMS GUI showing simulation output graphs +
+

Fig. 53 LEMS GUI showing simulation output graphs#

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample2.html b/Userdocs/LEMSExample2.html new file mode 100644 index 00000000..63502fb2 --- /dev/null +++ b/Userdocs/LEMSExample2.html @@ -0,0 +1,1055 @@ + + + + + + + + + + + Example 2: tidying up example 1 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 2: tidying up example 1

+ +
+ +
+
+ + + + +
+ +
+

Example 2: tidying up example 1#

+

This models is the same as in example 1, except that the definitions have been split out into several self-contained files.

+

The main file, included below, uses the Include element to include definitions from other files. +Each file is only read once, even if several files include it. +Because some of these files, such as the HH channel definitions, are intended to be used on their own, they include all the dimension definitions they need. +These may also occur in other files with the same dimension names. +This is fine as long as the dimensions being declared are the same. +An error will be reported if a new definition is supplied that changes any of the values. +The same applies for Unit definitions. +For other element types names and ids must be unique. +An id or name can’t appear twice, even if the content of the elements is the same.

+
+
+

Main model#

+

This defines a few components, then a network that uses them and a simulation to run it all. The HHCell component refers to channel types coming from the included hhmodels.xml file which in turn depends on hhcell.xml and hhchannel.xml.

+
<Lems>
+ 
+    <Target component="sim1"/>
+ 
+    <Include file="ex2dims.xml"/>
+    <Include file="hhchannel.xml"/> 
+ 
+    <Include file="hhcell.xml"/>
+    <Include file="spikegenerators.xml"/>
+    <Include file="hhmodels.xml"/>
+    <Include file="misciaf.xml"/> 
+
+    <Include file="SimpleNetwork.xml"/>
+
+    <HHCell id="hhcell_1" capacitance="1pF" injection="4pA" v0="-60mV">
+        <ChannelPopulation channel="na" number="6000" erev="50mV"/>
+        <ChannelPopulation channel="k" number="1800" erev="-77mV"/>
+    </HHCell>
+ 
+    <Component id="gen1" type="spikeGenerator" period="30ms"/>
+
+    <Component id="gen2" type="spikeGenerator2" period="32ms"/>
+
+    <Component id="iaf3cpt" type="iaf3" leakReversal="-50mV" deltaV="50mV" threshold="-30mV" leakConductance="50pS"
+           refractoryPeriod="4ms" capacitance="1pF"/>
+
+
+    <Network id="net1">
+        <Population id="p1" component="gen1" size="1"/>
+        <Population id="p2" component="gen2" size="1"/>
+        <Population id="p3" component="iaf3cpt" size="1"/>
+   
+        <Population id="hhpop" component="hhcell_1" size="1"/>
+    
+   
+        <EventConnectivity id="p1-p3" source="p1" target="p3">
+            <Connections type="AllAll"/>
+        </EventConnectivity>
+    </Network>
+    
+    <Include file="SingleSimulation.xml" />
+    
+    <Simulation id="sim1" length="80ms" step="0.01ms" target="net1">
+        <Display id="d0" title="Example 2" timeScale="1ms" xmin="-10" xmax="90" ymin="-90" ymax="60">
+            <Line id="tsince" quantity="p1[0]/tsince" scale="1ms" timeScale="1ms" color="#00c000" />
+            <Line id="p3v" quantity="p3[0]/v" scale="1mV" timeScale="1ms" color="#0000f0" />
+            <Line id="p0v" quantity="hhpop[0]/v" scale="1mV" timeScale="1ms" color="#ff4040" />
+        </Display>
+    </Simulation>
+
+</Lems>
+
+
+
+
+

Included files#

+
<Lems> 
+
+    <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
+    <Dimension name="time" t="1"/>
+    <Dimension name="per_time" t="-1"/>
+    <Dimension name="conductance" m="-1" l="-2" t="3" i="2"/>
+    <Dimension name="capacitance" m="-1" l="-2" t="4" i="2"/>
+    <Dimension name="current" i="1"/>
+    <Dimension name="temperature" k="1"/>
+
+    <Unit symbol="mV" dimension="voltage" power="-3"/> 
+    <Unit symbol="ms" dimension="time" power="-3"/> 
+    <Unit symbol="pS" dimension="conductance" power="-12"/>
+    <Unit symbol="nS" dimension="conductance" power="-9"/>
+    <Unit symbol="uF" dimension="capacitance" power="-6"/>
+    <Unit symbol="nF" dimension="capacitance" power="-9"/>
+    <Unit symbol="pF" dimension="capacitance" power="-12"/>
+    <Unit symbol="per_ms" dimension="per_time" power="3"/>
+    <Unit symbol="pA" dimension="current" power="-12"/>
+    <Unit symbol="nA" dimension="current" power="-9"/>
+    <Unit symbol="degC" dimension="temperature" offset="273.15"/>
+
+</Lems>
+
+
+

The file hhchannel.xml contains complete definitions of a fairly general HH-style channel model with any number of gates based on the three standard types used in the original HH work.

+
<Lems>
+
+    <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
+    <Dimension name="time" t="1"/>
+    <Dimension name="per_time" t="-1"/>
+    <Dimension name="conductance" m="-1" l="-2" t="3" i="2"/>
+    <Dimension name="capacitance" m="-1" l="-2" t="4" i="2"/>
+    <Dimension name="current" i="1"/>
+
+    
+    <ComponentType name="HHRate">
+        <Parameter name="rate" dimension="per_time"/>
+        <Parameter name="midpoint" dimension="voltage"/>
+        <Parameter name="scale" dimension="voltage"/>
+        <Requirement name="v" dimension="voltage"/>
+        <Exposure name="r" dimension="per_time"/>
+    </ComponentType>
+
+
+    <ComponentType name="HHExpRate" extends="HHRate">
+        <Dynamics>
+            <DerivedVariable name="r" exposure="r"  dimension="per_time" value="rate * exp((v - midpoint)/scale)"/>
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHSigmoidRate" extends="HHRate">
+        <Dynamics>
+            <DerivedVariable name="r" dimension="per_time" exposure="r" value="rate / (1 + exp( -(v - midpoint)/scale))"/>
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="HHExpLinearRate" extends="HHRate">
+        <Dynamics>
+            <DerivedVariable name="x" dimension="none" value="(v - midpoint) / scale"/>
+            <DerivedVariable name="r" dimension="per_time" exposure="r" value="rate * x / (1 - exp(-x))"/>
+        </Dynamics>
+    </ComponentType>
+ 
+
+    <ComponentType name="HHGate0">
+        <Parameter name="power" dimension="none"/> 
+        <Child name="Forward" type="HHRate"/>
+        <Child name="Reverse" type="HHRate"/>
+        <Requirement name="v" dimension="voltage"/>
+        <Exposure name="fcond" dimension="none"/>
+    
+        <Dynamics simultaneous="true">
+            <StateVariable name="q" dimension="none"/>
+            <DerivedVariable dimension="per_time" name="rf" select="Forward/r"/>
+            <DerivedVariable dimension="per_time" name="rr" select="Reverse/r"/> 
+            <TimeDerivative variable="q" value="rf * (1 - q) - rr * q"/>
+            <DerivedVariable name="fcond" dimension="none" exposure="fcond" value="q^power"/>
+        </Dynamics>    
+    </ComponentType>
+
+
+    <Include file="hhaltgate.xml"/>
+
+    
+    <ComponentType name="HHChannel">
+        <Parameter name="conductance" dimension="conductance"/>
+        <Children name="gates" type="HHGate"/>
+        <Exposure name="g" dimension="conductance"/>
+        <Dynamics simultaneous="false">
+            <DerivedVariable name="gatefeff" dimension="none" select="gates[*]/fcond" reduce="multiply"/>
+            <DerivedVariable name="g" exposure="g" dimension="conductance" value="conductance * gatefeff"/>
+        </Dynamics>
+    </ComponentType>
+
+
+</Lems>
+
+
+

As mentioned in example1, the numerics are too feeble to cope with this gate definition though, so a change of variables is employed instead:

+
<Lems>
+ 
+    <ComponentType name="HHGate">
+        <Parameter name="power" dimension="none"/> 
+        <Child name="Forward" type="HHRate"/>
+        <Child name="Reverse" type="HHRate"/>
+        <Requirement name="v" dimension="voltage"/>
+        <Exposure name="fcond" dimension="none"/>
+    
+   
+        <Dynamics simultaneous="false">
+            <StateVariable name="x" dimension="none"/>
+            <DerivedVariable name="ex" dimension="none" value="exp(x)"/>
+            <DerivedVariable name="q" dimension="none" value="ex / (1 + ex)"/>
+            <DerivedVariable name="rf" dimension="per_time" select="Forward/r"/>
+            <DerivedVariable name="rr" dimension="per_time" select="Reverse/r"/> 
+        
+            <TimeDerivative variable="x" value="(1 + ex)^2 / ex * (rf * (1 - q) - rr * q)"/>
+      
+            <DerivedVariable name="fcond" dimension="none" exposure="fcond" value="q^power"/>
+        </Dynamics>    
+    </ComponentType>
+
+</Lems>
+
+
+

The file hhcell.xml defines a simple cell model with some populations of HH channels.

+
<Lems>
+
+    <Include file="hhchannel.xml"/>
+
+    <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
+    <Dimension name="capacitance" m="-1" l="-2" t="4" i="2"/>
+    <Dimension name="current" i="1"/>
+
+    
+    <ComponentType name="ChannelPopulation">
+        <ComponentReference name="channel" type="HHChannel"/>
+        <Parameter name="number" dimension="none"/>
+        <Parameter name="erev" dimension="voltage"/>
+        <Requirement name="v" dimension="voltage"/>
+        <Exposure name="current" dimension="current"/>
+        <Exposure name="geff" dimension="conductance"/>
+  
+        <Structure>
+            <ChildInstance component="channel"/>
+        </Structure>
+  
+        <Dynamics simultaneous="false">
+            <DerivedVariable name="channelg" dimension="conductance" select="channel/g"/>
+            <DerivedVariable name="geff" exposure="geff" value="channelg * number"/>
+            <DerivedVariable name="current" exposure="current" value="geff * (erev - v)"/>
+        </Dynamics>
+    
+    </ComponentType>
+
+
+    <ComponentType name="HHCell">
+        <Parameter name="capacitance" dimension="capacitance"/>
+        <Children name="populations" type="ChannelPopulation"/>
+        <Parameter name="injection" dimension="current"/>
+        <Parameter name="v0" dimension="voltage"/>
+        <Exposure name="v" dimension="voltage"/>
+    
+        <Dynamics simultaneous="true">
+            <OnStart>
+                <StateAssignment variable="v" value="v0"/>
+            </OnStart>
+  
+            <DerivedVariable name="totcurrent" dimension="current" select="populations[*]/current" reduce="add"/>
+            <StateVariable name="v" exposure="v" dimension="voltage"/> 
+            <TimeDerivative variable="v" value="(totcurrent + injection) / capacitance"/>
+        </Dynamics>
+    </ComponentType>
+ 
+</Lems>
+
+
+

A couple of spike generators.

+
<Lems>
+
+    <Dimension name="time" t="1"/>
+ 
+
+    <ComponentType name="spikeGenerator">
+        <Parameter name="period" dimension="time"/>
+        <EventPort name="a" direction="out"/>
+        <Exposure name="tsince" dimension="time"/>
+        <Dynamics>
+            <StateVariable name="tsince" exposure="tsince" dimension="time"/>
+            <TimeDerivative variable="tsince" value="1"/>
+            <OnCondition test="tsince .gt. period">
+                <StateAssignment variable="tsince" value="0"/>
+                <EventOut port="a"/>
+            </OnCondition>
+        </Dynamics>
+    </ComponentType>
+
+
+    <ComponentType name="spikeGenerator2" extends="spikeGenerator">
+        <Dynamics>
+            <DerivedVariable name="tsince" exposure="tsince" value="t - tlast"/>
+            <StateVariable name="tlast" dimension="time"/>
+            <OnCondition test="t - tlast .gt. period">
+                <StateAssignment variable="tlast" value="t"/>
+                <EventOut port="a"/>
+            </OnCondition>
+        </Dynamics>
+    </ComponentType>
+ 
+
+</Lems>
+
+
+

And now the components themselves. +These are the standard HH sodium and potassium channels (as used in Rallpack3).

+
<Lems>
+    <Include file="hhchannel.xml"/>
+
+    <Unit symbol="mV" dimension="voltage" power="-3"/> 
+    <Unit symbol="per_ms" dimension="per_time" power="3"/>
+    <Unit symbol="pS" dimension="conductance" power="-12"/>
+
+    
+    <HHChannel id="na" conductance="20pS">
+        <HHGate id="m" power="3">
+            <Forward type="HHExpLinearRate" rate="1.per_ms" midpoint="-40mV" scale="10mV"/>
+            <Reverse type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV"/>
+        </HHGate>
+    
+        <HHGate id="h" power="1">
+            <Forward type="HHExpRate" rate="0.07per_ms" midpoint="-65.mV" scale="-20.mV"/>
+            <Reverse type="HHSigmoidRate" rate="1per_ms" midpoint="-35mV" scale="10mV"/>
+        </HHGate>
+    </HHChannel>
+
+
+    <HHChannel id="k" conductance="20pS">
+        <HHGate id="n" power="4">
+            <Forward type="HHExpLinearRate" rate="0.1per_ms" midpoint="-55mV" scale="10mV"/>
+            <Reverse type="HHExpRate" rate="0.125per_ms" midpoint="-65mV" scale="-80mV"/>
+        </HHGate>
+    </HHChannel>
+
+</Lems>
+
+
+

Some miscellaneous iaf models.

+
<Lems>
+    
+    <Include file="elecdims.xml"/>
+   
+
+    <ComponentType name="iaf1">
+        <Parameter name="threshold" dimension="voltage"/>
+        <Parameter name="refractoryPeriod" dimension="time"/>
+        <Parameter name="capacitance" dimension="capacitance"/>
+    </ComponentType>
+
+
+    <ComponentType name="iaf3" extends="iaf1">
+        <Parameter name="leakConductance" dimension="conductance"/>
+        <Parameter name="leakReversal" dimension="voltage"/>
+        <Parameter name="deltaV" dimension="voltage"/>
+        <EventPort name="spikes-in" direction="in"/>
+        <Exposure name="v" dimension="voltage"/>
+
+        <Dynamics>
+            <StateVariable name="v" exposure="v" dimension="voltage"/>
+            <TimeDerivative variable="v" value="leakConductance * (leakReversal - v) / capacitance"/>
+             
+            <OnEvent port="spikes-in">
+                <StateAssignment variable="v" value="v + deltaV"/>
+            </OnEvent>      
+        </Dynamics>
+
+    </ComponentType>
+ 
+
+</Lems>
+
+
+

Finally, a small collection of dimension definitions useful for things like the miscellaneous iaf cell definitions.

+
<Lems>
+    <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
+    <Dimension name="time" t="1"/>
+    <Dimension name="conductance" m="-1" l="-2" t="3" i="2"/>
+    <Dimension name="capacitance" m="-1" l="-2" t="4" i="2"/>
+    <Dimension name="current" i="1"/>
+    
+</Lems>
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample3.html b/Userdocs/LEMSExample3.html new file mode 100644 index 00000000..3acb2625 --- /dev/null +++ b/Userdocs/LEMSExample3.html @@ -0,0 +1,672 @@ + + + + + + + + + + + Example 3: Connection dependent synaptic components — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 3: Connection dependent synaptic components

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 3: Connection dependent synaptic components#

+

In many models, a synapse is only created where a connection exists. +This means that the model of the receiving cell should only declare that particular types of synapse can be added to it, not the actual synapse sub-components themselves.

+

Not much is needed beyond the elements described in example 1 except for some extensions to the component that declares the connectivity and a new child element in the component that the synapses are attached to. +The full example is shown below. +The synapse type includes an EventPort just like the previously defined cell type. +The cell type however includes a new child element: Attachments defined as:

+
<Attachments name="synapses" type="synapse" />
+
+
+

This operates rather like the Children element except that when a component is defined using this type the sub-elements are not included in the component definition. +Instead it indicates that instances of components of the particular type may be attached later when the model is actually run.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample4.html b/Userdocs/LEMSExample4.html new file mode 100644 index 00000000..62921455 --- /dev/null +++ b/Userdocs/LEMSExample4.html @@ -0,0 +1,833 @@ + + + + + + + + + + + Example 4: Kinetic schemes — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 4: Kinetic schemes

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 4: Kinetic schemes#

+

The existing components provide everything necessary to define types that allow a model to specify a kinetic scheme (Markov model). +The missing ingredient is the Dynamics element to actually expresses how instances of the components develop through time.

+

First then, the following definitions can be used to express ion channel models where the channel state is represented by an occupancy vector among a number of distinct states with rates for the transitions between states.

+
<ComponentType name="KSGate">
+   <Parameter name="power" dimension="none" />
+   <Parameter name="deltaV" dimension="voltage" />
+   <Children name="states" type="KSState" />
+   <Children name="transitions" type="KSTransition" />
+</ComponentType>
+<ComponentType name="KSState">
+   <Parameter name="relativeConductance" dimension="none" />
+   <Dynamics>
+      <StateVariable name="occupancy" dimension="none" />
+      <DerivedVariable name="q" value="relativeConductance * occupancy" />
+   </Dynamics>
+</ComponentType>
+<ComponentType name="KSClosedState" extends="KSState">
+   <Fixed parameter="relativeConductance" value="0" />
+</ComponentType>
+<ComponentType name="KSOpenState" extends="KSState">
+   <Fixed parameter="relativeConductance" value="1" />
+</ComponentType>
+<ComponentType name="KSTransition">
+   <Link name="from" type="KSState" />
+   <Link name="to" type="KSState" />
+   <Requirement name="v" dimension="voltage" />
+   <Exposure name="rf" dimension="per_time" />
+   <Exposure name="rr" dimension="per_time" />
+</ComponentType>
+<ComponentType name="KSChannel">
+   <Parameter name="conductance" dimension="conductance" />
+   <Children name="gates" type="KSGate" />
+   <Exposure name="g" dimension="conductance" />
+   <Dynamics>
+      <DerivedVariable name="fopen" dimension="none" select="gates[*]/fopen" reduce="multiply" />
+      <DerivedVariable name="g" exposure="g" dimension="conductance" value="fopen * conductance" />
+   </Dynamics>
+</ComponentType>
+
+
+

This says that a gate can contain any number of states and transitions. +A state has an occupancy variable, and a transition has links to two states giving the source and target states for the transition.

+

The transition element here is an abstract element because it doesn’t provide a Dynamics block but just specifies what quantities transitions should privide via the two exposures. +One of the most useful forms of transition is a damped Boltzman equation which can be parameterizd as follows:

+
<ComponentType name="VHalfTransition" extends="KSTransition">
+   <Parameter name="vHalf" dimension="voltage" />
+   <Parameter name="z" dimension="none" />
+   <Parameter name="gamma" dimension="none" />
+   <Parameter name="tau" dimension="time" />
+   <Parameter name="tauMin" dimension="time" />
+   <Constant name="kte" dimension="voltage" value="25.3mV" />
+   <Requirement name="v" dimension="voltage" />
+   <Dynamics>
+      <DerivedVariable name="rf0" dimension="per_time" value="exp(z * gamma * (v - vHalf) / kte) / tau" />
+      <DerivedVariable name="rr0" dimension="per_time" value="exp(-z * (1 - gamma) * (v - vHalf) / kte) / tau" />
+      <DerivedVariable name="rf" exposure="rf" dimension="per_time" value="1 / (1/rf0 + tauMin)" />
+      <DerivedVariable name="rr" exposure="rr" dimension="per_time" value="1 / (1/rr0 + tauMin)" />
+   </Dynamics>
+</ComponentType>
+
+
+

Given these definitions, we can express a couple of simple channel models that use kinetic schemes. +There is nothing special about these models. +They are just examples used in PSICS that produce spikes (albeit rather unnatural looking ones) when used together.

+
<KSChannel id="na1" conductance="20pS">
+   <KSGate power="1" deltaV="0.1mV">
+      <KSClosedState id="c1" />
+      <KSClosedState id="c2" />
+      <KSOpenState id="o1" relativeConductance="1" />
+      <KSClosedState id="c3" />
+      <VHalfTransition from="c1" to="c2" vHalf="-35mV" z="2.5" gamma="0.8" tau="0.15ms" tauMin="0.001ms" />
+      <VHalfTransition from="c2" to="o1" vHalf="-35mV" z="2.5" gamma="0.8" tau="0.15ms" tauMin="0.001ms" />
+      <VHalfTransition from="o1" to="c3" vHalf="-70mV" z="1.1" gamma="0.90" tau="8.0ms" tauMin="0.01ms" />
+   </KSGate>
+</KSChannel>
+<KSChannel id="k1" conductance="30pS">
+   <KSGate power="1" deltaV="0.1mV">
+      <KSClosedState id="c1" />
+      <KSOpenState id="o1" />
+      <VHalfTransition from="c1" to="o1" vHalf="0mV" z="1.5" gamma="0.75" tau="3.2ms" tauMin="0.3ms" />
+   </KSGate>
+</KSChannel>
+
+
+

This has all been done with the existing components. +They allow types to be defined for expressing kinetic schemes, and models can be expressed that use these types, but there is nothing so far that says that the model actually is governed by a kinetic scheme. +In particular, there is an “occupancy” state variable in each state element for which there is no governing equation and the rates generate “rf” and “rr” quantities that are not unused anywhere.

+

What is needed is a new element in the Dynamics block to link these together and say that the rates apply to the changes of occupancy among the state elements. +This is done by adding a KineticScheme element to the Dynamics block for a gate as follows (this now shows the full definition of the KSGate element):

+
<ComponentType name="KSGate">
+   <Parameter name="power" dimension="none" />
+   <Parameter name="deltaV" dimension="voltage" />
+   <Children name="states" type="KSState" />
+   <Children name="transitions" type="KSTransition" />
+   <Dynamics>
+      <KineticScheme name="ks">
+         <Nodes children="states" variable="occupancy" />
+         <Edges children="transitions" sourceNodeName="from" targetNodeName="to" forwardRate="rf" reverseRate="rr" />
+         <Tabulable variable="v" increment="deltaV" />
+      </KineticScheme>
+      <DerivedVariable name="q" dimension="none" select="states[*]/q" reduce="add" />
+      <DerivedVariable name="fopen" exposure="fopen" dimension="none" value="q^power" />
+   </Dynamics>
+</ComponentType>
+
+
+

The new part here is the KineticScheme element and its children Nodes, Edges and Tabulable. +The Nodes element says which elements in the parent container are goverened by the scheme, and which variable in those elements represents the relative occupancy.

+

The Edges element is a little more complicated. +It has to say not only which elements define the transitions, but how the fields in the transitions map to things the scheme knows about. +For a transition in a kinetic scheme, you need to know which state the transition comes from, which it goes to, and how fast it goes. +It is possible (as here) that a single transition defines both directions, in which case it must also say which variable in the target objects provides the reverse transition rates. +This is what the last four attributes of the Edges element do.

+

The Tabulable element is a temporary convenience for implementation purposes. +In this case it says that the rates depend only on v and that the transition matrices can be cached an reused on a grid of spacing deltaV rather than recomputed every time. +This is not used in the 0.2.1 version of the interpreter.

+

Note that the KineticScheme element doesn’t say anything about what the outputs are. +All it does is control the occupancy state variable in the state elements. +The interpretation of these quantities is specified in the normal way with the two DerivedVaraible declarations. +No special elements are needed in the scheme itself.

+

To actually use these models we need cell and population elements to link them all together. +There is nothing new here - it all works just as for HH channels. +The rest of the example4.xml file is:

+
<ComponentType name="ChannelPopulation">
+   <ComponentRef name="channel" type="KSChannel" />
+   <Parameter name="number" dimension="none" />
+   <Parameter name="erev" dimension="voltage" />
+   <Requirement name="v" dimension="voltage" />
+   <Dynamics>
+      <DerivedVariable name="channelg" dimension="conductance" select="channel/g" />
+      <DerivedVariable name="geff" value="channelg * number" />
+      <DerivedVariable name="current" value="geff * (erev - v)" />
+   </Dynamics>
+</ComponentType>
+<ComponentType name="KSCell">
+   <Parameter name="capacitance" dimension="capacitance" />
+   <Children name="populations" type="ChannelPopulation" />
+   <Parameter name="injection" dimension="current" />
+   <Parameter name="v0" dimension="voltage" />
+   <Dynamics>
+      <OnStart>
+         <StateAssignment variable="v" value="v0" />
+      </OnStart>
+      <DerivedVariable name="totcurrent" dimension="current" select="sum(populations[*]/current)" />
+      <StateVariable name="v" dimension="voltage" />
+      <TimeDerivative variable="v" value="(totcurrent + injection) / capacitance" />
+   </Dynamics>
+</ComponentType>
+<KSCell id="kscell_1" capacitance="1pF" injection="1pA" v0="-60mV">
+   <ChannelPopulation channel="na1" number="600" erev="50mV" />
+   <ChannelPopulation channel="k1" number="180" erev="-77mV" />
+</KSCell>
+
+<Network id="net1">
+   <XPopulation id="kspop" component="kscell_1" size="1" />
+</Network>
+
+<Simulation length="80ms" step="0.07ms" target="net1">
+   <Display timeScale="ms">
+      <Line quantity="kspop[0]/v" scale="mV" color="#ff4040" />
+   </Display>
+</Simulation>
+
+
+

When run, this produces:

+
+LEMS GUI showing simulation output graphs +
+

Fig. 54 LEMS GUI showing simulation output graphs#

+
+
+

There are clearly some initialization issues but the basic Dynamics is the same as the PSICS version of this model.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample5.html b/Userdocs/LEMSExample5.html new file mode 100644 index 00000000..e5b04715 --- /dev/null +++ b/Userdocs/LEMSExample5.html @@ -0,0 +1,937 @@ + + + + + + + + + + + Example 5: References and paths — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 5: References and paths

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 5: References and paths#

+

The ChannelPopulation type used earlier repeats a common model specification error in that it makes the reversal potential of a population of channels a parameter of the population (often it is made a parameter of the channel specification, which is equally bad):

+
<ComponentType name="ChannelPopulation">
+   <ComponentRef name="channel" type="KSChannel" />
+   <Parameter name="number" dimension="none" />
+   <Parameter name="erev" dimension="voltage" />
+</ComponentType>
+
+
+

In fact, of course, the reversal potential is not a property of a channel population, or of a channel. +It depends on the environment the channel is put in and the ions it is permeable to. +But, it is needed in the Dynamics specification for the population so just putting it in as a parameter solves the immediate problem. +In the process, however, it introduces the potential for easily creating contradictory models, by, for example setting different reversals for populations of the same type of channel.

+

A much better approach is to let the channel just say what it is permeable to. +Some other element in the model can define the membrane reversal potentials for different channels, and the channel population object should then look up the relevant value for the permeant ion of its channel. +This provides a cleaner expression of what is there, removes redundancy and lowers the entropy of the model specification.

+

The following three types are sufficient to provide a simple framework to centralize the definitions of species and reversal potentials on one place:

+
<ComponentType name="Species">
+   <Text name="name" />
+   <Parameter name="charge" dimension="none" />
+</ComponentType>
+<ComponentType name="Environment">
+   <Children name="membranePotentials" type="MembranePotential" />
+</ComponentType>
+<ComponentType name="MembranePotential">
+   <ComponentRef name="species" type="Species" />
+   <Parameter name="reversal" dimension="voltage" />
+</ComponentType>
+
+
+

Once these are available, they can be used to define some species, and to create an environment component that sets their reversal potentials:

+
<Species id="Na" name="Sodium" charge="1" />
+<Species id="K" name="Potassium" charge="1" />
+<Species id="Ca" name="Calcium" charge="1" />
+<Environment id="env1">
+   <MembranePotential species="Na" reversal="50mV" />
+   <MembranePotential species="K" reversal="-80mV" />
+</Environment>
+
+
+

The next step is to add a species reference to the channel type, so that channel definitions can say what species they are permeant to.

+
<ComponentType name="KSChannel">
+   <Parameter name="conductance" dimension="conductance" />
+   <ComponentRef name="species" type="Species" />
+   <Children name="gates" type="KSGate" />
+   <Dynamics>
+      <DerivedVariable name="fopen" dimension="none" select="gates[*]/fopen" reduce="multiply" />
+      <DerivedVariable name="g" dimension="conductance" value="fopen * conductance" />
+   </Dynamics>
+</ComponentType>
+
+
+

Finally the channel population type needs modifying to add a derived parameter that addresses the reversal potential from the membrane properties:

+
<ComponentType name="ChannelPopulation">
+   <ComponentRef name="channel" type="KSChannel" />
+   <Parameter name="number" dimension="none" />
+   <Requirement name="v" dimension="voltage" />
+   <DerivedParameter name="erev" dimension="voltage" select="//MenbranePotential[species = channel/species]/reversal" />
+   <Dynamics>
+      <DerivedVariable name="channelg" dimension="conductance" select="channel/g" />
+      <DerivedVariable name="geff" value="channelg * number" />
+      <DerivedVariable name="current" value="geff * (erev - v)" />
+   </Dynamics>
+</ComponentType>
+
+
+

This introduces a new construct, the DerivedParameter specification that defines a local parameter “erev” to hold the quantity from the specified path:

+
<DerivedParameter name="erev" dimension="voltage" select="//MenbranePotential[species = channel/species]/reversal" />
+
+
+

The path here uses XPath like syntax operating on the component tree in the model. +In this case, it finds all the elements of thpe MembranePotential in the model. +The predicate selects the one for which the species is the same as the species referred to from the channel used for this population. +Finally, it takes the “reversal” parameter from the membrane potential component. +This is made locally available as the parameter “erev”.

+

The Dynamics of this model is exactly the same as example 4. +The full model including both the type definitions and the components is included below.

+
<Lems>
+
+    <Target component="sim1"/>
+
+    <Include file="ex2dims.xml"/>
+
+    <ComponentType name="Species">
+        <Text name="name"/>
+        <Parameter name="charge" dimension="none"/>
+    </ComponentType>
+
+
+    <ComponentType name="Environment">
+        <Children name="membranePotentials" type="MembranePotential"/>
+    </ComponentType>
+
+
+    <ComponentType name="MembranePotential">
+        <ComponentReference name="species" type="Species"/>
+        <Parameter name="reversal" dimension="voltage"/>
+    </ComponentType>
+
+    <Species id="Na" name="Sodium" charge="1"/>
+    <Species id="K" name="Potassium" charge="1"/>
+    <Species id="Ca" name="Calcium" charge="1"/>
+
+
+    <Environment id="env1">
+        <MembranePotential species="Na" reversal="50mV"/>
+        <MembranePotential species="K" reversal="-80mV"/>    
+    </Environment>
+
+
+    <ComponentType name="KSChannel">
+        <Parameter name="conductance" dimension="conductance"/>
+        <ComponentReference name="species" type="Species"/>
+        <Children name="gates" type="KSGate"/>
+        <Exposure name="g" dimension="conductance"/>
+    
+        <Dynamics>
+            <DerivedVariable name="fopen" dimension="none" select="gates[*]/fopen" reduce="multiply"/>
+            <DerivedVariable name="g" exposure="g" dimension="conductance" value="fopen * conductance"/>
+        </Dynamics>
+    </ComponentType>
+
+
+    
+    <ComponentType name="KSGate">
+        <Parameter name="power" dimension="none"/>
+        <Parameter name="deltaV" dimension="voltage"/>
+        <Children name="states" type="KSState"/>
+        <Children name="transitions" type="KSTransition"/>
+        <Exposure name="fopen" dimension="none"/>
+    
+        <Dynamics>   
+            <KineticScheme name="ks" nodes="states" stateVariable="occupancy"
+                           edges="transitions" edgeSource="from" edgeTarget="to" 
+                           forwardRate="rf" reverseRate="rr" dependency="v" step="deltaV"/>
+    
+            <DerivedVariable name="q" dimension="none" select="states[*]/q" reduce="add"/>
+            <DerivedVariable name="fopen" exposure="fopen" dimension="none" value="q^power"/>
+        </Dynamics>
+    </ComponentType>
+
+    
+    <ComponentType name="KSState">
+        <Parameter name="relativeConductance" dimension="none"/>
+        <Exposure name="q" dimension="none"/>
+        <Exposure name="occupancy" dimension="none"/>
+   
+        <Dynamics>
+            <StateVariable name="occupancy" exposure="occupancy" dimension="none"/>
+            <DerivedVariable name="q" exposure="q" value="relativeConductance * occupancy"/>
+        </Dynamics>
+    </ComponentType>
+
+    <ComponentType name="KSClosedState" extends="KSState">
+        <Fixed parameter="relativeConductance" value="0"/>
+    </ComponentType>
+
+
+    <ComponentType name="KSOpenState" extends="KSState">
+        <Fixed parameter="relativeConductance" value="1"/>
+    </ComponentType>
+
+
+    <ComponentType name="KSTransition">
+        <Link name="from" type="KSState"/>
+        <Link name="to" type="KSState"/>
+        <Exposure name="rf" dimension="per_time"/>
+        <Exposure name="rr" dimension="per_time"/>
+ 
+    </ComponentType>
+
+
+    <ComponentType name="VHalfTransition" extends="KSTransition">
+        <Parameter name="vHalf" dimension="voltage"/>
+        <Parameter name="z" dimension="none"/>
+        <Parameter name="gamma" dimension="none"/>
+        <Parameter name="tau" dimension="time"/>
+        <Parameter name="tauMin" dimension="time"/>
+        <Constant name="kte" dimension="voltage" value="25.3mV"/>
+        <Requirement name="v" dimension="voltage"/>  
+    
+        <Dynamics>
+            <DerivedVariable name="rf0" dimension="per_time" value="exp(z * gamma * (v - vHalf) / kte) / tau"/>
+            <DerivedVariable name="rr0" dimension="per_time" value="exp(-z * (1 - gamma) * (v - vHalf) / kte) / tau"/>
+            <DerivedVariable name="rf" exposure="rf" dimension="per_time" value="1 / (1/rf0 + tauMin)"/>
+            <DerivedVariable name="rr" exposure="rr" dimension="per_time" value="1 / (1/rr0 + tauMin)"/>
+        </Dynamics>
+    </ComponentType>
+
+
+
+
+
+
+    <KSChannel id="na1" conductance="20pS" species="Na">
+        <KSGate power="1" deltaV="0.1mV">
+            <KSClosedState id="c1"/>
+            <KSClosedState id="c2"/>
+            <KSOpenState id="o1" relativeConductance="1"/>
+            <KSClosedState id="c3"/>
+            <VHalfTransition from="c1" to="c2" vHalf = "-35mV" z="2.5" gamma="0.8" tau="0.15ms" tauMin="0.001ms"/>
+            <VHalfTransition from="c2" to="o1" vHalf = "-35mV" z="2.5" gamma="0.8" tau="0.15ms" tauMin="0.001ms"/>
+            <VHalfTransition from="o1" to="c3" vHalf = "-70mV" z="1.1" gamma="0.90" tau="8.0ms" tauMin="0.01ms"/>         
+        </KSGate>
+    </KSChannel>
+
+
+    <KSChannel id="k1" conductance="30pS" species="K">
+        <KSGate power="1" deltaV="0.1mV">
+            <KSClosedState id="c1"/>
+            <KSOpenState id="o1"/>
+            <VHalfTransition from="c1" to="o1" vHalf = "0mV" z="1.5" gamma="0.75" tau="3.2ms" tauMin="0.3ms"/>
+        </KSGate>
+    </KSChannel>
+
+
+
+
+    <ComponentType name="ChannelPopulation">
+        <ComponentReference name="channel" type="KSChannel"/>
+        <Parameter name="number" dimension="none"/>
+        <Requirement name="v" dimension="voltage"/>
+        <Exposure name="current" dimension="current"/>
+        <DerivedParameter name="erev" dimension="voltage" select="//MembranePotential[species=channel/species]/reversal"/>
+        <Dynamics>
+     
+            <DerivedVariable name="channelg" dimension="conductance" select="channel/g"/>
+            <DerivedVariable name="geff" value="channelg * number"/>
+            <DerivedVariable name="current" exposure="current" value="geff * (erev - v)"/>
+        </Dynamics>    
+    
+    
+        <Structure>    
+            <ChildInstance component="channel"/>    
+        </Structure>
+    </ComponentType>
+
+
+
+
+    <ComponentType name="KSCell">
+        <Parameter name="capacitance" dimension="capacitance"/>
+        <ComponentReference name="environment" type="Environment"/>
+        <Children name="populations" type="ChannelPopulation"/>
+        <Parameter name="injection" dimension="current"/>
+        <Parameter name="v0" dimension="voltage"/>
+        <Exposure name="v" dimension="voltage"/>
+        <Dynamics>
+            <OnStart>
+                <StateAssignment variable="v" value="v0"/>
+            </OnStart>
+  
+            <DerivedVariable name="totcurrent" dimension="current" select="populations[*]/current" reduce="add"/>
+            <StateVariable name="v" exposure="v" dimension="voltage"/> 
+            <TimeDerivative variable="v" value="(totcurrent + injection) / capacitance"/>
+        </Dynamics>
+    </ComponentType>
+
+
+
+    <KSCell id="kscell_1" capacitance="0.4pF" injection="1pA" v0="-60mV" environment="env1">
+        <ChannelPopulation channel="na1" number="400"/>
+        <ChannelPopulation channel="k1" number="180"/>
+    </KSCell>
+
+    
+    <Include file="SingleSimulation.xml" />
+    
+    <Simulation id="sim1" length="80ms" step="0.05ms" target="kscell_1">
+        <Display id="d0" title="Example 5: References and paths" timeScale="1ms" xmin="-10" xmax="90" ymin="-90" ymax="60">
+            <Line id="v" quantity="v" scale="1mV" timeScale="1ms" color="#0000f0"/>
+        </Display>
+    </Simulation>
+
+</Lems>
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample6.html b/Userdocs/LEMSExample6.html new file mode 100644 index 00000000..ea785768 --- /dev/null +++ b/Userdocs/LEMSExample6.html @@ -0,0 +1,723 @@ + + + + + + + + + + + Example 6: User defined types for simulation and display — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 6: User defined types for simulation and display

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 6: User defined types for simulation and display#

+

Up until now, the examples have used a set of simple Simulation, Display and Line constructs without explaining how they are defined. +This shows what is needed in the Dynamics block to let the user defined types to specify that they actually define a runnable simulation or settings that can be used to display results.

+

This means that the user can select their own names for the different parameters required for a simulation, and, more importantly, simulation and display attributes can be added to existing type definitions to make multi-faceted type definitions that can both be run on their own or as part of a larger simulation.

+

Example 6 shows two new elements that can be used in the Dynamics block, Run and Show as illustrated in the following user-defined type that defines a simulation:

+
<ComponentType name="Simulation">
+   <Parameter name="length" dimension="time" />
+   <Parameter name="step" dimension="time" />
+   <ComponentRef name="target" type="HHCell" />
+   <Children name="displays" type="Display" />
+   <Dynamics>
+      <StateVariable name="t" dimension="time" />
+      <Run component="target" variable="t" increment="step" total="length" />
+      <Show src="displays" />
+   </Dynamics>
+</ComponentType>
+
+
+

The ‘component’ attribute of the Run element specifies which parameter of the type contains the reference to the component that should actually be run. +The ‘step’ and ‘increment’ attributes specify the parameters that hold the timestep and total runtime. +The ‘variable’ attribute is for future use - at present, the independent variable is always ‘t’.

+

A Run element can be added to the Dynamics block in any type definition to make it independently runnable.

+

Running a simulation without any output is rarely much use, so there are two futher elements that can be included in the Dynamics block: Show and Record. +The ‘src’ attribute of the Show element points to the components that should be shown. +These in turn can contain other Show elements but eventually everything pointed to by a Show element should contain one or more Record elements. +These specify what will actually be sent as output. +They have the path to the variable as the ‘quantity’ attribute, its scale as the ‘scale’ attribute and the line color for plotting.

+

The following two types show one way that these can be combined to allow the user to express a display object containing one or more lines.

+
<ComponentType name="Display">
+   <Parameter name="timeScale" dimension="time" />
+   <Children name="lines" type="Line" />
+   <Dynamics>
+      <Show src="lines" scale="timeScale" />
+   </Dynamics>
+</ComponentType>
+<ComponentType name="Line">
+   <Parameter name="scale" dimension="*" />
+   <Text name="color" />
+   <Path name="quantity" />
+   <Dynamics>
+      <Record quantity="quantity" scale="scale" color="color" />
+   </Dynamics>
+</ComponentType>
+
+
+

Once these have been defined, a component can be constructed that uses them as follows:

+
<Simulation id="sim1" length="80ms" step="0.05ms" target="hhcell_1">
+   <Display timeScale="1ms">
+      <Line id="V" quantity="v" scale="1mV" color="#0000f0" />
+      <Line id="Na_q" quantity="NaPop/geff" scale="1nS" color="#f00000" />
+      <Line id="K_q" quantity="KPop/geff" scale="1nS" color="#00f000" />
+   </Display>
+</Simulation>
+
+
+

When run, this produces the output shown below:

+
+LEMS GUI showing simulation output graphs +
+

Fig. 55 LEMS GUI showing simulation output graphs#

+
+
+

Note how the scale attributes are set to 1mV and 1nS for the different lines so that they show up on the same axes.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample7.html b/Userdocs/LEMSExample7.html new file mode 100644 index 00000000..b8490f1b --- /dev/null +++ b/Userdocs/LEMSExample7.html @@ -0,0 +1,824 @@ + + + + + + + + + + + Example 7: User defined types for networks and populations — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 7: User defined types for networks and populations

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 7: User defined types for networks and populations#

+

This example shows how the standard component type structures can be used to declare components for simple networks. +The following three definitions allow networks to be constructed containing fixed size populations of a particular component type.

+
<ComponentType name="Network">
+   <Children name="populations" type="Population" />
+   <Children name="connectivities" type="EventConnectivity" />
+</ComponentType>
+<ComponentType name="Population">
+   <ComponentRef name="component" type="Component" />
+   <Parameter name="size" dimension="none" />
+</ComponentType>
+<ComponentType name="EventConnectivity">
+   <Link name="source" type="Population" />
+   <Link name="target" type="Population" />
+   <Child name="Connections" type="ConnectionPattern" />
+</ComponentType>
+
+
+

The harder part is to provide elements in the Dynamics blocks to express what should be done with components based on these types. +The Network element doesn’t pose any problems because the default behavior on instantiation will do the right thing: it will instantiate each of the child populations and EventConnectivity elements.

+

But the population element needs to say that its instantiation involves making ‘size’ instances of the component referred to by the ‘component’ reference, where ‘size’ is the value supplied for the size parameter in a component specification. +This can be done by including a Build element inside the Dynamics block:

+
<ComponentType name="Population">
+   <ComponentRef name="component" type="Component" />
+   <Parameter name="size" dimension="none" />
+   <Dynamics>
+      <Build>
+         <MultiInstantiate number="size" component="component" />
+      </Build>
+   </Dynamics>
+</ComponentType>
+
+
+

The MultiInstantiate specification says that there should be ‘size’ instances of the component referred to in the ‘component’ parameter created when the model is built. +This overrides the default behavior. +[TODO: what is the Build element content corresponding to the default behavior?].

+

This serves to create some rather simple populations. +More complex specifications, such as putting one instance at each point of a grid satisfying a particular constraint could be handled via first declaring elements to form the grid, and then using selectors that pick the points in the population element to actually put the cells at [its not clear to me how much more would be required to make this work, other than implementing proper xpath-like selectors].

+

The following three types define a general connectivity structure with an abstract ConnectionPattern type, and a specific instance for All-All connectivity.

+
<ComponentType name="EventConnectivity">
+   <Link name="source" type="Population" />
+   <Link name="target" type="Population" />
+   <Child name="Connections" type="ConnectionPattern" />
+</ComponentType>
+<ComponentType name="ConnectionPattern">
+</ComponentType>
+<ComponentType name="AllAll" extends="ConnectionPattern">
+   <Dynamics>
+      <Build>
+         <ForEach instances="../source" as="a">
+            <ForEach instances="../target" as="b">
+               <EventConnection from="a" to="b" />
+            </ForEach>
+         </ForEach>
+      </Build>
+   </Dynamics>
+</ComponentType>
+
+
+

The Build element in the AllAll pattern uses a new ForEach construct and the EventConnectin element from before. +The ForEach element operates selects each instance matching its ‘instances’ attribute, and applies the enclosing directives, much in the same way as for-each in XSL. +The proof of concept interpreter also has Choose, When and Otherwise elements that operate much like their XSL equivalents, although these are not used in this example.

+

With these definitions in place, a network simulation can be defined with the following:

+
<Network id="net1">
+   <Population id="p1" component="gen1" size="2" />
+   <Population id="p3" component="iaf3cpt" size="3" />
+   <EventConnectivity id="p1-p3" source="p1" target="p3">
+      <Connections type="AllAll" />
+   </EventConnectivity>
+</Network>
+
+<Simulation id="sim1" length="80ms" step="0.05ms" target="net1">
+   <Display timeScale="1ms">
+      <Line id="gen_v" quantity="p3[0]/v" scale="1mV" color="#0000f0" />
+      <Line id="gen_tsince" quantity="p1[0]/tsince" scale="1ms" color="#00c000" />
+   </Display>
+</Simulation>
+
+
+

The output when the model is run is shown below, followed by the full listing.

+
+LEMS GUI showing simulation output graphs +
+

Fig. 56 LEMS GUI showing simulation output graphs#

+
+
+
<Lems>
+ 
+    <Target component="sim1"/> 
+ 
+ 
+    <Include file="ex2dims.xml"/>
+    <Include file="spikegenerators.xml"/>
+    <Include file="misciaf.xml"/>
+
+ 
+    <Component id="gen1" type="spikeGenerator" period="30ms"/>
+
+    <Component id="gen2" type="spikeGenerator2" period="32ms"/>
+
+    <Component id="iaf3cpt" type="iaf3" leakReversal="-50mV" deltaV="50mV" threshold="-30mV" leakConductance="50pS"
+           refractoryPeriod="4ms" capacitance="1pF"/>
+
+
+    <ComponentType name="Network">
+        <Children name="populations" type="Population"/>
+        <Children name="connectivities" type="EventConnectivity"/>
+    </ComponentType>
+
+
+    <ComponentType name="Population">
+        <ComponentReference name="component" type="Component"/>
+        <Parameter name="size" dimension="none"/>
+   
+        <Structure>
+            <MultiInstantiate number="size" component="component"/>
+        </Structure>
+  
+    </ComponentType>
+
+
+    <ComponentType name="EventConnectivity">
+        <Link name="source" type="Population"/>
+        <Link name="target" type="Population"/>
+        <Child name="Connections" type="ConnectionPattern"/>
+    </ComponentType>
+
+
+    <ComponentType name="ConnectionPattern"/>
+
+
+    <ComponentType name="AllAll" extends="ConnectionPattern">
+        <Structure>
+            <ForEach instances="../source" as="a">
+                <ForEach instances="../target" as="b">
+                    <EventConnection from="a" to="b"/>
+                </ForEach>
+            </ForEach>    
+        </Structure>
+    </ComponentType>
+
+
+    <Network id="net1">
+        <Population id="p1" component="gen1" size="2"/>
+        <Population id="p3" component="iaf3cpt" size="3"/>
+     
+        <EventConnectivity id="p1-p3" source="p1" target="p3">
+            <Connections type="AllAll"/>
+        </EventConnectivity>
+    </Network>
+
+
+    <Include file="SingleSimulation.xml" />
+    
+    <Simulation id="sim1" length="80ms" step="0.05ms" target="net1">
+        <Display id="d0" title="Example 7: User defined types for networks and populations" timeScale="1ms" xmin="-10" xmax="90" ymin="-50" ymax="90">
+            <Line id="gen_v" quantity="p3[0]/v" scale="1mV" timeScale="1ms" color="#0000f0"/>
+            <Line id="gen_tsince" quantity="p1[0]/tsince" scale="1ms" timeScale="1ms" color="#00c000"/>
+        </Display>
+    </Simulation>
+
+</Lems>
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSExample8.html b/Userdocs/LEMSExample8.html new file mode 100644 index 00000000..dbd8badb --- /dev/null +++ b/Userdocs/LEMSExample8.html @@ -0,0 +1,835 @@ + + + + + + + + + + + Example 8: Regimes in Dynamics definitions — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Example 8: Regimes in Dynamics definitions

+ +
+
+ +
+
+
+ + + + +
+ +
+

Example 8: Regimes in Dynamics definitions#

+

This example introduces the Regime, Transition and OnEntry elements within a Dynamics block. +Rather than having a single state instance, the entity can be on one of the defined regimes at any given time. +The Transition element occurring inside a condition block serves to move it from one regime to another. +The OnEntry block inside a regime can contain initialization directives that apply each time the entity enters that regime.

+
<ComponentType name="refractiaf">
+   <Parameter name="threshold" dimension="voltage" />
+   <Parameter name="refractoryPeriod" dimension="time" />
+   <Parameter name="capacitance" dimension="capacitance" />
+   <Parameter name="vleak" dimension="voltage" />
+   <Parameter name="gleak" dimension="conductance" />
+   <Parameter name="current" dimension="current" />
+   <Parameter name="vreset" dimension="voltage" />
+   <Parameter name="deltaV" dimension="voltage" />
+   <Parameter name="v0" dimension="voltage" />
+   <EventPort name="out" direction="out" />
+   <EventPort name="in" direction="in" />
+   <Dynamics>
+      <StateVariable name="v" dimension="voltage" />
+      <OnStart>
+         <StateAssignment variable="v" value="v0" />
+      </OnStart>
+      <Regime name="refr">
+         <StateVariable name="tin" dimension="time" />
+         <OnEntry>
+            <StateAssignment variable="tin" value="t" />
+            <StateAssignment variable="v" value="vreset" />
+         </OnEntry>
+         <OnCondition test="t .gt. tin + refractoryPeriod">
+            <Transition regime="int" />
+         </OnCondition>
+      </Regime>
+      <Regime name="int" initial="true">
+         <TimeDerivative variable="v" value="(current + gleak * (vleak - v)) / capacitance" />
+         <OnCondition test="v .gt. threshold">
+            <EventOut port="out" />
+            <Transition regime="refr" />
+         </OnCondition>
+         <OnEvent port="in">
+            <StateAssignment variable="v" value="v + deltaV" />
+         </OnEvent>
+      </Regime>
+   </Dynamics>
+</ComponentType>
+
+
+

Full listing:

+
<Lems>
+
+    <Target component="sim1"/> 
+
+
+    <Include file="ex2dims.xml"/>
+    <Include file="spikegenerators.xml"/>
+    <Include file="misciaf.xml"/>
+
+
+    <ComponentType name="refractiaf">
+        <Parameter name="threshold" dimension="voltage"/>
+        <Parameter name="refractoryPeriod" dimension="time"/>
+        <Parameter name="capacitance" dimension="capacitance"/>
+        <Parameter name="vleak" dimension="voltage"/>
+        <Parameter name="gleak" dimension="conductance"/>
+
+        <Parameter name="current" dimension="current"/>
+        <Parameter name="vreset" dimension="voltage"/>
+        <Parameter name="deltaV" dimension="voltage"/>
+        <Parameter name="v0" dimension="voltage"/>
+
+        <EventPort name="out" direction="out"/>
+        <EventPort name="in" direction="in"/>
+
+        <Exposure name="v" dimension="voltage"/>
+
+        <Dynamics>     
+            <StateVariable name="v" exposure="v" dimension="voltage" /> 
+            <StateVariable name="tin" dimension="time"/>       
+            
+            <OnStart>
+                <StateAssignment variable="v" value="v0"/>
+            </OnStart>
+
+            <Regime name="refr">         
+                <OnEntry>             
+                    <StateAssignment variable="tin" value="t" />             
+                    <StateAssignment variable="v" value="vreset" />          
+                </OnEntry>                   
+                <OnCondition test="t .gt. tin + refractoryPeriod">                 
+                    <Transition regime="int" />             
+                </OnCondition>         
+            </Regime>          
+
+            <Regime name="int" initial="true">         
+                <TimeDerivative variable="v" value="(current + gleak * (vleak - v)) / capacitance" />         
+                <OnCondition test="v .gt. threshold">             
+                    <EventOut port="out" />             
+                    <Transition regime="refr" />         
+                </OnCondition>         
+                <OnEvent port="in">
+                    <StateAssignment variable="v" value="v + deltaV"/>
+                </OnEvent>
+
+            </Regime>
+        </Dynamics>
+
+    </ComponentType>
+
+
+    <Component id="gen1" type="spikeGenerator" period="7ms"/>
+
+    
+    <Component id="multiregime" type="refractiaf" threshold="-50mV" v0="-80mV"
+               refractoryPeriod="20ms" capacitance="1pF" vreset="-80mV" vleak="-90mV" 
+               gleak="5pS" current="0.00001nA" deltaV="5mV"/>
+
+
+    <ComponentType name="Network">
+        <Children name="populations" type="Population"/>
+        <Children name="connectivities" type="EventConnectivity"/>
+    </ComponentType>
+
+
+    <ComponentType name="Population">
+        <ComponentReference name="component" type="Component"/>
+        <Parameter name="size" dimension="none"/>
+        <Structure>
+                <MultiInstantiate number="size" component="component"/>
+        </Structure>
+    </ComponentType>
+
+
+    <ComponentType name="EventConnectivity">
+        <Link name="source" type="Population"/>
+        <Link name="target" type="Population"/>
+        <Child name="Connections" type="ConnectionPattern"/>
+    </ComponentType>
+
+
+    <ComponentType name="ConnectionPattern"/>
+
+
+    <ComponentType name="AllAll" extends="ConnectionPattern">
+        <Structure>
+            <ForEach instances="../source" as="a">
+                <ForEach instances="../target" as="b">
+                    <EventConnection from="a" to="b"/>
+                </ForEach>
+            </ForEach>    
+        </Structure>
+    </ComponentType>
+
+
+    <Network id="net1">
+        <Population id="p1" component="gen1" size="1"/>
+        <Population id="p3" component="multiregime" size="2"/>
+
+        <EventConnectivity id="p1-p3" source="p1" target="p3">
+            <Connections type="AllAll"/>
+        </EventConnectivity>
+    </Network>
+
+
+    <Include file="SingleSimulation.xml" />
+
+    <Simulation id="sim1" length="80ms" step="0.05ms" target="net1">
+        <Display id="d0" title="Example 8: Regimes in dynamics definitions" timeScale="1ms" xmin="-10" xmax="90" ymin="-90" ymax="20">
+            <Line id="gen_vmr" quantity="p3[0]/v" scale="1mV" timeScale="1ms" color="#00c000"/>
+            <Line id="gen_sv" quantity="p1[0]/tsince" scale="1ms" timeScale="1ms" color="#f00000"/>
+        </Display>
+    </Simulation>
+
+
+</Lems>
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSOverview.html b/Userdocs/LEMSOverview.html new file mode 100644 index 00000000..581df88e --- /dev/null +++ b/Userdocs/LEMSOverview.html @@ -0,0 +1,854 @@ + + + + + + + + + + + Model structure overview — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Model structure overview

+ +
+ +
+
+ + + + +
+ +
+

Model structure overview#

+

Models are based on user-defined types (the term ComponentType is used in the XML) that contain parameter declarations, reference declarations and specification of what children an instance of a type can have. +Typically they also contain a Dynamics specification which can contain build-time and run-time declarations. +Build-time declarations apply when a simulation is set up, for example to connect cells. +Run-time declarations specify the state variables, equations and events that are involved.

+

An instance of a ComponentType is a model Component It specifies a particular set of parameters for a given ComponentType. It says nothing about state variables: in a simulation, typically many run-time instances will correspond to a single model component definition, and several model component definitions will use the same type. +A run-time instance holds its own set of state variables as defined by the Type definition and a reference to its component for the parameter values specific to that particular model component. +The update rules come from the type definition. +As such, neither the ComponentType nor the Component is properly a “prototype” for the runtime instance.

+
+

Defining ComponentTypes#

+

ComponentTypes are declared as, for example:

+
<ComponentType name="myCell">
+   <Parameter name="threshold" dimension="voltage" />
+</ComponentType>
+
+
+

A Component based on such a type is expressed as:

+
<Component type="myCell" threshold="dimensional_quantity" />
+
+
+

The quoted value for ‘threshold’ here is a rich quantity with size and dimensions, typically consisting of a numerical value and a unit symbol. +Assignments like this are the only place unit symbols can occur. +Equations and expressions relate rich types, independent of any particular unit system.

+

An equivalent way of writing the above in shorthand notation (using an example of a string with size and dimension for threshold) is:

+
<myCell threshold="-30 mV" />
+
+
+

A type can contain elements for specifying the following aspects of the structure and parameters of a model component:

+
    +
  • Parameter - dimensional quantities that remain fixed within a model

  • +
  • Child - a required single sub-component of a given type

  • +
  • Children - variable number of sub-components of the given type

  • +
  • ComponentRef - a reference to a top-level component definition.

  • +
  • Link - a reference to a component definition relative to the referrer

  • +
  • Attachments - for build-time connections

  • +
  • EventPort - for run-time discrete event communication

  • +
  • Exposure - quantities that can be accessed from other components

  • +
  • Requirement - quantities that must be accessible to the component for it to make sense

  • +
  • DerivedParameter - like parameters, but derived from some other quantity in the model

  • +
+

The “EventPort” and “Attachments” declarations don’t have any corresponding elements in their model component specification. +They only affect how the component can be used when a model is instantiated. +EventPorts specify that a model can send or receive events, and should match up with declarations in its Dynamics specification. +An “Attachments” declaration specifies that a run-time instance can have dynamically generated attachments as, for example, when a new synapse run-time instance is added to a cell for each incoming connection.

+
+
+

Inheritance#

+

A type can extend another type, adding new parameters, or supplying values (SetParam) for inherited parameters. +As well as reducing duplication, the key application of this is with the Child and Children declarations, where a type can specify that it needs a child or children of a particular supertype, but doesn’t care about which particular sub-type is used in a model. +This applies, for example, where a cell requires synapses that compute a quantity with dimensions current, but doesn’t need access to any other parts of the synapse Dynamics.

+
+
+

Run-time Dynamics#

+

Run time Dynamics are included within a Dynamics block in a type specification. +They include declaration of:

+
    +
  • state variables

  • +
  • first order differential equations with respect to time of state variables

  • +
  • derived quantities - things computed in terms of other local quantities or computed from other run-time instances

  • +
+

Run time Dynamics can be grouped into Regimes, where only one regime is operative at a given time for a particular run-time instance. +Regimes have access to all the variables in the parent instance and can define their own local variables.

+

Dynamics can also contain event blocks:

+
    +
  • OnStart blocks contain any initialization declarations needed when a run-time state is instantiated

  • +
  • OnEvent blocks specify what happens when an event is received on a specified port

  • +
  • OnEntry blocks (only within regimes) specify things that should happen each time the system enters that regime.

  • +
  • OnCondition blocks have a test condition and specify what should happen when it is met.

  • +
+

Blocks may contain state variable assignments, event sending directives and transition directives to indicate that the system should change from one regime to another.

+
+
+

Build-time Structure#

+

Build-time Structure defines the structure of a multi-component model. +Currently there are:

+
    +
  • MultiInstantiate - for declaring that a component yields multiple run-time instances corresponding to a particular model component. Eg, for defining populations of cells.

  • +
  • ForEach - for iterating over multiple instances in the run-time structure

  • +
  • EventConnection - for connecting ports between run-time instances

  • +
+
+
+

Other#

+

There are also Run, Show and Record Dynamics for creating type definitions that define simulations and what should be recorded or displayed from such a simulation.

+
+
+

Observations#

+

The numerous references to “run-time instances” above is problematic, since the structures do not dictate any particular way of building a simulator or running a model. +In particular, there is no requirement that a component or Dynamics declaration should give rise to any particular collection of state variables that could be interpreted as a run-time instance in the state of a simulator.

+

So, it is convenient to think of eventual state instances, and that is indeed how the reference interpreter works, but the model specification structure should avoid anything that is specific to this picture.

+
+
+

Type specification examples#

+

Examples of type definitions using the various types of child element:

+
<ComponentType name="synapse">
+   <EventPort direction="in" />
+</ComponentType>
+
+
+

says that instances of components using this type can receive events.

+
<ComponentType name="HHChannel">
+   <Children name="gates" type="HHGate" />
+</ComponentType>
+
+
+

says that a HHChannel can have gates.

+
<ComponentType name="HHGate">
+   <Child name="Forward" type="HHRate" />
+   <Child name="Reverse" type="HHRate" />
+</ComponentType>
+
+
+

says that a HHGate has two children called Forward and Reverse, each of type HHRate.

+
<ComponentType name="synapseCell">
+   <Attachments name="synapses" type="synapse" />
+</ComponentType>
+
+
+

says that instances of components based on the synapseCell type can have instances of component based on the synapse type attached to them at build time.

+
<ComponentType name="Population">
+   <ComponentRef name="component" type="Component" />
+</ComponentType>
+
+
+

says that components based on the Population type need a reference to a component of type Component (ie, anything) (which would then be used as the thing to be repeated in the population, but it doesn’t say that here).

+
<ComponentType name="EventConnectivity">
+   <Link name="source" type="Population" />
+</ComponentType>
+
+
+

says that EventConnectivity components need a relative path to a local component of type Population which will be accessed via the name “source”. +The model component declarations corresponding to the channel and gate types would be:

+
<Component type="HHChanne">
+   <Component type="HHGate">
+      <Component type="some_hh_gate_type" role="Forward" />
+      <Component type="some_hh_gate_type" role="Reverse" />
+   </Component>
+</Component>
+
+
+

or, in the shorthand notation:

+
<HHChannel>
+   <HHGate>
+      <Forward type="some_hh_gate_type" />
+      <Reverse type="some_hh_gate_type" />
+   </HHGate>
+</HHChannel>
+
+
+

For the population type it would be:

+
<Component id="myPopulation" type="population" component="myCellModel" />
+
+
+

And for the connections:

+
<Component type="EventConnectivity" source="myPopulation" />
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSSchema.html b/Userdocs/LEMSSchema.html new file mode 100644 index 00000000..ca333fc9 --- /dev/null +++ b/Userdocs/LEMSSchema.html @@ -0,0 +1,687 @@ + + + + + + + + + + + LEMS — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

LEMS

+ +
+
+ +
+
+
+ + + + +
+ +
+

LEMS#

+

The current version of the LEMS specification is 0.7.6 and the schema for this can be seen here. +The following figure, taken from Cannon et al. 2014 ([CGC+14]) shows the structure of LEMS models. +The following pages give details of all the elements that are included in LEMS. +For examples on LEMS, and using LEMS to extend NeuroML, please see the relevant sections in the documentation.

+
+Structure of LEMS models +
+

Fig. 58 (A) Models in LEMS are specified using ComponentType definitions with nested +Dynamics elements. Any Parameter or StateVariable declaration must refer to a +Dimension element defined at the top level. A Component element sets parameter +values for a particular instance of a ComponentType. Each Parameter value must +refer to one of the Unit elements defined at the top level. The Dynamics +element supports continuous time systems defined in terms of first order +differential equations, and event driven processing as specified by the various +“On…” elements. Multiple Regimes, each with independent TimeDerivative +expressions can be defined, along with the rules to transition between them. +(B) Example of a ComponentType, the passive channel model from Figure 1. +© The XML equivalent of the ComponentType (top) and Component (bottom) for this +model. (D) Defining containment in LEMS, using Child (exactly one sub element +of the given type) or Children (zero or multiple copies). (E) Extension in +LEMS. Extending ComponentTypes inherit the structure of the base type. Example +Components in XML are shown in (D,E).#

+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMSSimulation.html b/Userdocs/LEMSSimulation.html new file mode 100644 index 00000000..ebb6f011 --- /dev/null +++ b/Userdocs/LEMSSimulation.html @@ -0,0 +1,791 @@ + + + + + + + + + + + LEMS Simulation files — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

LEMS Simulation files#

+

For many users, the most obvious place that LEMS is used is in the LEMS Simulation file (usually LEMS_*.xml).

+

In short, what a file like this does is:

+
    +
  • point at the NeuroML file containing the model to simulate

  • +
  • include any other LEMS file it needs, including the NeuroML core type definitions

  • +
  • specify how long to run the simulation for and the simulation timestep (dt)

  • +
  • say what to display when the simulation has finished (e.g. membrane potentials of selected cells)

  • +
  • say what to save to file, e.g. voltage traces, spike times

  • +
+

These files are crucial in many of the workflows for simulating NeuroML models, and are reused across different simulator targets, e.g. jnml LEMS_MyNetwork.xml (run in jNeuroML), jnml LEMS_MyNetwork.xml -neuron (convert to NEURON), jnml LEMS_MyNetwork.xml -brian2 (convert to Brian2). See here for more information.

+
+LEMS Simulation file and NeuroML file +
+

Fig. 61 Typical organisation for a NeuroML simulation. The main NeuroML model is specified in a file with the network (*.net.nml), which can include/point to files containing individual synapses (*.synapse.nml) or cell files (*.cell.nml). If the latter are conductance based, they may include external channel files (*.channel.nml). The main LEMS Simulation file only needs to include the network file, and tools for running simulations of the model refer to just this LEMS file. Exceptions to these conventions are frequent and simulations will run perfectly well with all the elements inside the main LEMS file, but using this scheme will maximise reusability of model elements.#

+
+
+
+

Specification of format#

+

See here for definition of the main elements used in the file, including Display, OutputFile, etc.

+
+
+

Quantities and paths#

+

Specifying the quantities to save/display in a LEMS Simulation file is an important and sometimes confusing process. There is a dedicated page on quantities and paths in LEMS and NeuroML2.

+
+
+

Creating LEMS Simulation files#

+

Perhaps the easiest way to create a LEMS Simulation file is to base it off of an existing example.

+
<Lems>
+
+    <!-- Specify the Simulation element below as what LEMS should load. Save a
+         report of the simulation (e.g. simulator version, run time) in a file-->
+    <Target component="sim1" reportFile="report.txt"/>
+
+    <Include file="Cells.xml"/>
+    <Include file="Networks.xml"/>
+    <Include file="Simulation.xml"/>
+
+    <!-- Including file with a <neuroml> root, a "real" NeuroML 2 file -->
+    <Include file="NML2_SingleCompHHCell.nml"/>
+
+    <!-- What to run (from the above NeuroML file) and what duration/timestep -->
+    <Simulation id="sim1" length="300ms" step="0.01ms" target="net1">
+
+        <!-- Display a trace in a new window -->
+        <Display id="d1" title="HH cell with simple morphology: voltage" timeScale="1ms" xmin="0" xmax="300" ymin="-90" ymax="50">
+                <Line id="v" quantity="hhpop[0]/v" color="#cccccc" scale="0.001" timeScale="1ms"/>
+        </Display>
+
+        <!-- Save a variable to file  -->
+        <OutputFile id="of0" fileName="ex_v.dat">
+            <OutputColumn id="v" quantity="hhpop[0]/v"/>
+        </OutputFile>
+
+        <!-- Save spike times from a cell to file  -->
+        <EventOutputFile id="spikes" fileName="ex.spikes" format="TIME_ID">
+            <EventSelection id="0" select="hhpop[0]" eventPort="spike"/>
+        </EventOutputFile>
+
+    </Simulation>
+
+</Lems>
+
+
+

Alternatively, it is possible to create a LEMS Simulation file in Python file using pyNeuroML:

+
from pyneuroml.lems import LEMSSimulation
+
+ls = LEMSSimulation('sim1', 500, 0.05, 'net1')
+ls.include_neuroml2_file('NML2_SingleCompHHCell.nml')
+
+ls.create_display('display0', "Voltages", "-90", "50")
+ls.add_line_to_display('display0', "v", "hhpop[0]/v", "1mV", "#ffffff")
+
+ls.create_output_file('Volts_file', "v.dat")
+ls.add_column_to_output_file('Volts_file', 'v', "hhpop[0]/v")
+
+ls.save_to_file()
+
+
+

See this example for more details.

+
+
+

What about SED-ML?#

+

The Simulation Experiment Description Markup Language (SED-ML) is used by a number of other initiatives such as SBML for specifying simulation setup, execution and basic analysis.

+

We chose to have a LEMS specific format for specifying simulations in NeuroML2 as opposed to natively supporting SED-ML, mainly because of the tight link to the LEMS language and jLEMS package, i.e. all of the NeuroML2 elements and elements in a LEMS simulation file have underlying definitions in the LEMS language. However it is possible to convert the LEMS simulation to the equivalent in SED-ML.

+
+

Exporting LEMS simulation descriptions to SED-ML#

+
# Using jnml
+jnml <LEMS simulation file> -sedml
+
+# Using pynml
+pynml <LEMS simulation file> -sedml
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/DefiningComponents.html b/Userdocs/LEMS_elements/DefiningComponents.html new file mode 100644 index 00000000..5341ab58 --- /dev/null +++ b/Userdocs/LEMS_elements/DefiningComponents.html @@ -0,0 +1,750 @@ + + + + + + + + + + + Defining Components — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Defining Components

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Defining Components#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Component#

+

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

id

String

name

String

Name by which the component was declared - this shouldn’t be accessible.

declaredType

String

Name by which the component was declared - this shouldn’t be accessible.

type

String

eXtends

String

+
+ +
+ ++++ + + + + + + + + + + + + + + +

insertions

Insertion

components

Component

abouts

About

metas

Meta

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Definingcomponenttypes.html b/Userdocs/LEMS_elements/Definingcomponenttypes.html new file mode 100644 index 00000000..d0391e84 --- /dev/null +++ b/Userdocs/LEMS_elements/Definingcomponenttypes.html @@ -0,0 +1,1499 @@ + + + + + + + + + + + Defining component types — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Defining component types#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

ComponentType#

+

Root element for defining LEMS Component Types.

+
+ +
+ +++++ + + + + + + + + + + +

name

String

The name of the component type. This can be uses as an XML element name in the shorthand form whendefining components.

eXtends

String

The component type that this type inherits field definitions for, if any

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

parameters

Parameter

indexParameters

IndexParameter

derivedParameters

DerivedParameter

pathParameters

PathParameter

requirements

Requirement

componentRequirements

ComponentRequirement

instanceRequirements

InstanceRequirement

exposures

Exposure

childs

Child

childrens

Children

links

Link

componentReferences

ComponentReference

componentTypeReferences

ComponentTypeReference

locations

Location

propertys

Property

dynamicses

Dynamics

structures

Structure

simulations

Simulation

equilibriums

Equilibrium

procedures

Procedure

geometrys

Geometry

fixeds

Fixed

constants

Constant

attachmentses

Attachments

eventPorts

EventPort

paths

Path

texts

Text

collections

Collection

pairCollections

PairCollection

abouts

About

metas

Meta

+
+
+
+
+

Parameter#

+

A quantity, defined by name and dimension, that must be supplied when a Component of the enclosing ComponentType is defined

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

The name of the parameter. This is the name of the attribute to be used when the parameter is supplied in a component definition

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the parameter

+
+
+
+
+

PathParameter#

+

A parameter of which the value is a path expression. When a ComponentType declares a PathParameter, a corresponding Component definition should have an attibute with that name whose value is a path expression that evaluates within the instance tree of the built model. This is used, for example, in the definition of a group component class, where the coresponding component specifies a path over the instance tree which selectesthe items that should go in the group.

+
+ +
+ +++++ + + + + + + +

name

String

Name of the parameter

+
+
+
+
+

Property#

+

An property on an instance of a component. Unlike a Parameter, a Property can very from instance to instance. It should be set with an Assign element within the build specification.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

dimension

String

defaultValue

String

The defaultValue for the property must be a plain number (no units) giving the SI magnitude of the quantity.

+
+
+
+
+

DerivedParameter#

+

A parameter that is a function of the Component’s Parameters, which does not change with time. Its value can be supplied either with the ‘value’ attribute that evaluates within the scope of the definition, or with the ‘select’ attribute which gives a path to ‘primary’ version of the parameter. For example, setting select=‘//MembranePotential[species=channel/species]/reversal’ within the appropriate context allows a channel’s reversal potential to taken from a single global setting according to its permeant ion, rather than explicitly supplied locally.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

name

String

The name of the derived parameter

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the derived parameter

select

String

Path to the parameter that supplies the value. Exactly one of ‘select’ and ‘value’ is required.

value

String

A string defining the value of the element

+
+
+
+
+

Fixed#

+

Fixes the value of a parameter in the parent class, so that it does not have to be supplied separately in component definitions.

+
+ +
+ +++++ + + + + + + + + + + +

parameter

String

value

String

+
+
+
+
+

Requirement#

+

A Requirement gives the name and dimension of a quantity (parameter or variable) that should be accessible within the scope of a model component. This is only applicable for elements that can be included as children of other elements, where the scope comprises its own parameters and those in the scope of its enclosing element. Once a requirement has been declared, then the quantity can be used within the Dynamics definition of the component. It is the responsibility of an implementation to check that the component is only used in a context in which the requirement is met. A typical example is in defining membrand bound components which require access to the membrane potential but where the variable that holds the potential itself is defined in the top level component.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

name

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the requirement

+
+
+
+
+

ComponentRequirement#

+

The name of a component or component reference that must exist in the component hierarchy

+
+ +
+ +++++ + + + + + + +

name

String

name

+
+
+
+
+

InstanceRequirement#

+

An instance that must be supplied at build time. Expressions can contain references to quantities in the instance

+
+ +
+ +++++ + + + + + + +

name

String

name

+
+
+
+
+

Exposure#

+

A quantity that is made available to other components in the simulation. Note that all variables in a Dynamics definition are private. If other components need access to them, then the definition should explicitly link them to an exposure defined in the component class

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

Name of the exposure element

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the element

+
+
+
+
+

Child#

+

Specifies that a component can have a child of a particular type. The name supplied here can be used in path expressions to access the component. This is useful, for example, where a component can have multiple children of the same type but with different roles, such as the forward and reverse transition rates in a channel.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

Name of the child

type

String

Reference to a component class, the value should be the name of the target class.

description

String

An optional description of the child

+
+
+
+
+

Children#

+

Specifies that a component can have children of a particular class. The class may refer to an extendedtype, in which case components of any class that extends the specified target class should be valid as child components

+
+ +
+ +++++ + + + + + + + + + + +

name

String

Name of the children

type

String

The class of component allowed as children.

+
+
+
+ +
+

ComponentReference#

+

A reference to another component. The target component can be accessed with path expressions in the same way as a child component, but can be defined independently

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

A name for the ComponentReference

type

String

The type of the target Component

description

String

An optional description of the ComponentReference

+
+
+
+
+

ComponentTypeReference#

+

This is used in conjunction with PathParameter elements to specify the target class of selections defined within components operating over the instance tree.

+
+ +
+ +++++ + + + + + + +

name

String

+
+
+
+
+

Collection#

+

Specifies that instances of components based on this class can containe a named collection of other instances. This provides for containers for oprating on groups of instances with path and filter expressions defined in components to operate over the instance tree.

+
+ +
+ +++++ + + + + + + +

name

String

+
+
+
+
+

PairCollection#

+

Defines a named collection of paris of instances, similar to the Collection element.

+
+ +
+ +++++ + + + + + + +

name

String

+
+
+
+
+

EventPort#

+

A port on a component that can send or receive events, depending on the direction specified

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

Name of the EventPort

direction

String

‘IN’ or ‘OUT’

description

String

An optional description of the EventPort

+
+
+
+
+

Text#

+

Holds textual information that does not change the model but is needed for other purposes such as labelling graphs.

+
+ +
+ +++++ + + + + + + + + + + +

name

String

The textual content

description

String

An optional description of the element

+
+
+
+
+

Path#

+

Duplicates some functionality of PathParameter - the two should be merged.

+
+ +
+ +++++ + + + + + + +

name

String

+
+
+
+
+

Attachments#

+

Specifies that a component can accept attached components of a particular class. Attached components can be added at build time dependent on other events. For scoping and access purposes they are like child components. The cannonical use of attachments is in adding synapses to a cell when a network connection is made.

+
+ +
+ +++++ + + + + + + + + + + +

name

String

A name for the Attachments

type

String

The type of the Attachments

+
+
+
+
+

Insertion#

+

+
+
+

IntegerParameter#

+

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

The name of the parameter. This is the name of the attribute to be used when the parameter is supplied in a component definition

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the parameter

+
+
+
+
+

IndexParameter#

+

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

The name of the parameter. This is the name of the attribute to be used when the parameter is supplied in a component definition

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the parameter

+
+
+
+
+

About#

+

+
+
+

Meta#

+

Meta element to provide arbitrary metadata to LEMS simulations. Note that this is not processed by the LEMS interpreter.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Dynamics.html b/Userdocs/LEMS_elements/Dynamics.html new file mode 100644 index 00000000..8c4e18c0 --- /dev/null +++ b/Userdocs/LEMS_elements/Dynamics.html @@ -0,0 +1,1275 @@ + + + + + + + + + + + Dynamics — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Dynamics#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Dynamics#

+

Specifies the dynamical behavior of components build from this ComponentType. Note that all variables in a Dynamics definition are private. If other components need access to them, then the definition should explicitly link them to an Exposure defined in the component class

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

supers

Super

derivedVariables

DerivedVariable

conditionalDerivedVariables

ConditionalDerivedVariable

stateVariables

StateVariable

timeDerivatives

TimeDerivative

kineticSchemes

KineticScheme

onStarts

OnStart

onEvents

OnEvent

onConditions

OnCondition

stateScalarFields

StateScalarField

derivedScalarFields

DerivedScalarField

derivedPunctateFields

DerivedPunctateField

regimes

Regime

+
+
+
+
+

StateVariable#

+

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

name

String

Name of the state variable

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

exposure

String

If this variable is to be accessed from outside, it should be linked to an Exposure that is defined in the ComponentType.

description

String

An optional description of the state variable

+
+
+
+
+

StateAssignment#

+

Has ‘variable’ and ‘value’ fields

+
+ +
+ +++++ + + + + + + + + + + +

variable

String

The name of the variable

value

String

A string defining the value of the element

+
+
+
+
+

TimeDerivative#

+

First order differential equations, functions of StateVariables and Parameters, for how StateVariables change with time. Has a variable and a value. The value is the rate of change of the variable.

+
+ +
+ +++++ + + + + + + + + + + +

variable

String

The name of the variable

value

String

A string defining the value of the element

+
+
+
+
+

DerivedVariable#

+

A quantity that depends algebraically on other quantities in the model. The ‘value’ field can be set to a mathematical expression, or the ‘select’ field to a path expression. If the path expression produces multiple matches, then the ‘reduce’ field says how these are reduced to a single value by taking the sum or product.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

name

String

Name of the derived variable

select

String

A path to the variable that supplies the value. Note that to select a variable from another component, the variable must be marked as an Exposure. Exactly one of ‘select’ and ‘value’ is required

dimension

String

The dimension, or ‘none’. This should be the name of an already defined dimension element

description

String

An optional description of the derived variable

reduce

String

Either ‘add’ or ‘multiply’. This applies if ther are multiple matches to the path or if ‘required’ is false. In the latter case, for multiply mode, multiplicative expressions in this variable behave as if the term was absent. Additive expressions generate an error. Conversely, if set to ‘add’ then additive expressions behave as if it was not there and multiplicative ones generateand error.

exposure

String

required

boolean

Set to true if it OK for this variable to be absent. See ‘reduce’ for what happens in this case

value

String

A string defining the value of the element

+
+
+
+
+

OnStart#

+

+
+ +
+ ++++ + + + + + + + + + + + +

stateAssignments

StateAssignment

eventOuts

EventOut

transitions

Transition

+
+
+
+
+

OnCondition#

+

+
+ +
+ ++++ + + + + + + + + + + + +

stateAssignments

StateAssignment

eventOuts

EventOut

transitions

Transition

+
+
+
+
+

OnEvent#

+

Event handler block

+
+ +
+ +++++ + + + + + + +

port

String

the port to listen on

+
+ +
+ ++++ + + + + + + + + + + + +

stateAssignments

StateAssignment

eventOuts

EventOut

transitions

Transition

+
+
+
+
+

EventOut#

+

+
+
+

KineticScheme#

+

Allows the specification of systems that can be in one of a small number of states at any time with probabilistic transitions between states. This includes continuous time Markov processes as are used for stochastic models of ion channels. A kinetic scheme does not itself introduce any new elements or state variables. It is rather a way of connecting quantities in existing components by saying that quantities in the edge elements should be interpreted as transition rates among quantities in the node elements.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

name

String

Name of kinetic scheme

nodes

String

Source of notes for scheme

edges

String

The element that provides the transitions for the scheme

stateVariable

String

Name of state variable in state elements

edgeSource

String

The name of the attribute in the rate element that defines the source of the transition

edgeTarget

String

Attribute tha defines the target

forwardRate

String

Name of forward rate exposure

reverseRate

String

Name of reverse rate exposure

+
+
+
+
+

Regime#

+

Allows the dynamics of a ComponentType to be expressed via a finite state machine. Each regime has its internal dynamics, and conditions on which transitions between regimes occur are specified using the OnCondition element

+
+ +
+ +++++ + + + + + + + + + + +

name

String

The name of the regime

initial

String

‘True’ if this is the initial regime of the system

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

derivedVariables

DerivedVariable

stateVariables

StateVariable

timeDerivatives

TimeDerivative

onStarts

OnStart

onEntrys

OnEntry

onEvents

OnEvent

onConditions

OnCondition

requiredVars

lemsschema:requiredvar_

+
+
+
+
+

OnEntry#

+

+
+ +
+ ++++ + + + + + + + + + + + +

stateAssignments

StateAssignment

eventOuts

EventOut

transitions

Transition

+
+
+
+
+

Transition#

+

+
+
+

Super#

+

+
+
+

ConditionalDerivedVariable#

+

+
+ +
+ +++++ + + + + + + + + + + + + + + +

name

String

dimension

String

exposure

String

+
+ +
+ ++++ + + + + + +

cases

Case

+
+
+
+
+

Case#

+

+
+ +
+ +++++ + + + + + + +

value

String

A string defining the value of the element

+
+
+
+
+

Equilibrium#

+

+
+ +
+ ++++ + + + + + +

derivedVariables

DerivedVariable

+
+
+
+
+

StateScalarField#

+

+
+
+

DerivedScalarField#

+

+
+
+

DerivedPunctateField#

+

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Geometry.html b/Userdocs/LEMS_elements/Geometry.html new file mode 100644 index 00000000..6335778f --- /dev/null +++ b/Userdocs/LEMS_elements/Geometry.html @@ -0,0 +1,761 @@ + + + + + + + + + + + Geometry — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Geometry

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Geometry#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Geometry#

+

Specifies the geometrical interpretation of the properties of components realizing this ComponentType.

+
+ +
+ ++++ + + + + + + + + + + + +

frustums

Frustum

solids

Solid

skeletons

Skeleton

+
+
+
+
+

Frustum#

+

+
+
+

Solid#

+

+
+
+

Location#

+

+
+
+

Skeleton#

+

+
+ +
+ ++++ + + + + + +

scalarFields

ScalarField

+
+
+
+
+

ScalarField#

+

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Modelstructure.html b/Userdocs/LEMS_elements/Modelstructure.html new file mode 100644 index 00000000..1d387844 --- /dev/null +++ b/Userdocs/LEMS_elements/Modelstructure.html @@ -0,0 +1,823 @@ + + + + + + + + + + + Model structure — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Model structure

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Model structure#

+

Models can be spread over multiple files. The root element in each file is Lems.

+
+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Lems#

+

Root element for any lems content

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + +

dimensions

Dimension

constants

Constant

units

Unit

assertions

Assertion

componentTypes

ComponentType

components

Component

targets

Target

+
+
+
+
+

Target#

+

A lems file can contain many component definitions. A Target elements specifies that a components should be treated as the entry point for simulation or other processing

+
+ +
+ +++++ + + + + + + + + + + + + + + +

component

String

Reference to the entry point component

reportFile

String

Optional attribute specifying file in which to save short report of simulation

timesFile

String

Optional attribute specifying file in which to save times used in simulation

+
+
+
+
+

Constant#

+

A constant quantity: like a parameter for which the value is supplied in the class definition itself rather than when a component is defined.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

name

String

A readable name for the constant.

symbol

String

The symbol used in expressions to refer to this constant.

value

String

The value of a constant must be a plain number (no units) giving the SI magnitude of the quantity or an expression involving only plain numbers or other constants.

dimension

String

+
+
+
+
+

Include#

+

Include LEMS files in other LEMS files. Files are included where the Include declaration occurs. The enclosing Lems block is stripped off and the rest of the content included as is

+
+ +
+ +++++ + + + + + + +

file

String

the name or relative path of a file to be included

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Procedure.html b/Userdocs/LEMS_elements/Procedure.html new file mode 100644 index 00000000..6989efd6 --- /dev/null +++ b/Userdocs/LEMS_elements/Procedure.html @@ -0,0 +1,743 @@ + + + + + + + + + + + Procedure — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Procedure

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Procedure#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Procedure#

+

+
+ +
+ ++++ + + + + + +

statements

lemsschema:statement_

+
+
+
+
+

Equilibrate#

+

+
+
+

ForEachComponent#

+

+
+ +
+ ++++ + + + + + +

statements

lemsschema:statement_

+
+
+
+
+

Print#

+

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Simulation.html b/Userdocs/LEMS_elements/Simulation.html new file mode 100644 index 00000000..a036fc51 --- /dev/null +++ b/Userdocs/LEMS_elements/Simulation.html @@ -0,0 +1,840 @@ + + + + + + + + + + + Simulation — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Simulation

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Simulation#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Simulation#

+

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + + + + +

records

Record

eventRecords

EventRecord

runs

Run

dataDisplays

DataDisplay

dataWriters

DataWriter

eventWriters

EventWriter

+
+
+
+
+

Record#

+

+
+ +
+ +++++ + + + + + + + + + + + + + + +

quantity

String

path to the parameter that will contain the path to the quantity to be recorded

scale

String

path to the element that defines the scale for rendering the quantity dimensionless

color

String

hex format color suggestion for how the data should be displayed

+
+
+
+
+

EventRecord#

+

+
+ +
+ +++++ + + + + + + + + + + +

quantity

String

path for the component which will emit spikes to be recorded

eventPort

String

event port for the component which will emit spikes

+
+
+
+
+

DataDisplay#

+

+
+
+

DataWriter#

+

+
+
+

EventWriter#

+

+
+
+

Run#

+

The run element provides a way to make a model runnable. It should point to the parameters that set the step size etc. The target parameters have to be dimensionally consistent.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

component

String

name of the component reference that will set the component to be run

variable

String

increment

String

path to the parameter that sets the step size

total

String

path to the parameter that sets the total span of the independent variable to be run

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Structure.html b/Userdocs/LEMS_elements/Structure.html new file mode 100644 index 00000000..8c112ad9 --- /dev/null +++ b/Userdocs/LEMS_elements/Structure.html @@ -0,0 +1,1097 @@ + + + + + + + + + + + Structure — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Structure#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Structure#

+

By default, each Component in a model gives rise to a single instance of its state variables when the model is executed. The state variables are then governed by the dynamics definition in the associated ComponentType. Elements in the Structure declaration can be used to change this behavior, for example to make multiple instances of the state variables, or to instantiate a different component. A typical application for the latter would be a Component that defines a population of cells. The population Component might define the number of cells it contains but would refer to a Component defined elsewhere for the actual cell model to use.

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

BuildElement#

+

Base class for elements that can be used in Structures

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

MultiInstantiate#

+

+
+ +
+ ++++ + + + + + + + + +

assigns

Assign

buildElements

BuildElement

+
+
+
+
+

CoInstantiate#

+

+
+ +
+ ++++ + + + + + + + + +

assigns

Assign

buildElements

BuildElement

+
+
+
+
+

Assign#

+

+
+
+

Choose#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

ChildInstance#

+

+
+ +
+ ++++ + + + + + + + + +

assigns

Assign

buildElements

BuildElement

+
+
+
+
+

ForEach#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

EventConnection#

+

+
+ +
+ ++++ + + + + + + + + +

assigns

Assign

buildElements

BuildElement

+
+
+
+
+

Tunnel#

+

+
+ +
+ ++++ + + + + + + + + +

assigns

Assign

buildElements

BuildElement

+
+
+
+
+

PairsEventConnection#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

PairFilter#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

IncludePair#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

With#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

If#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

Apply#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

Gather#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+

GatherPairs#

+

+
+ +
+ ++++ + + + + + +

buildElements

BuildElement

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/LEMS_elements/Unitsanddimensions.html b/Userdocs/LEMS_elements/Unitsanddimensions.html new file mode 100644 index 00000000..9a5782fe --- /dev/null +++ b/Userdocs/LEMS_elements/Unitsanddimensions.html @@ -0,0 +1,812 @@ + + + + + + + + + + + Units and dimensions — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Units and dimensions

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Units and dimensions#

+

Generated on 22/08/23. +Please file any issues or questions at the issue tracker here.

+
+
+

Dimension#

+

A Dimenson element associated a name with a particular combination of the standards SI base dimensions, mass, lenght, time, current, temperature and amount if substance (moles). Fractional dimensions are not currently supported.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

name

String

The name to be used when referring to this dimension from variable declaration or units

m

int

Mass

l

int

Length

t

int

Time

i

int

Current

k

int

Temperature

n

int

Amount of substance

j

int

Luminous intensity

+
+
+
+
+

Unit#

+

A Unit asociates a symbol with a dimension and a power of ten. For non-metric units a scale can be provided, as in ‘1 inch = 0.0254 m’. In this case there is a degeneracy between the power and the scale which is best resolved by not using the two together. The offset parameter is available for units which are not zero-offset, such as farenheit.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

name

String

As with constants, units are only referred to within expressions using their symbols, so the name is just for readability.

symbol

String

The symbol is used to refer to this unit inside compound expressions coutaining a number and a unit symbol. Such expressions can only occur on the right hand side of assignments statements.

dimension

String

Reference to the dimension for this unit

power

int

Power of ten

scale

double

Scale, only to be used for scales which are not powers of ten

offset

double

Offset for non zero-offset units

+
+
+
+
+

Assertion#

+

Assertions are not strictly part of the model, but can be included in a file as a consistency check.

+
+ +
+ +++++ + + + + + + + + + + +

dimension

String

The name of a dimension

matches

String

An expression involving dimensions. The dimensionality of the expression should match the dimensionality of the dimension reference.

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/MissionAndAims.html b/Userdocs/MissionAndAims.html new file mode 100644 index 00000000..7d4f852d --- /dev/null +++ b/Userdocs/MissionAndAims.html @@ -0,0 +1,675 @@ + + + + + + + + + + + Mission and Aims — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Mission and Aims

+ +
+
+ +
+
+
+ + + + +
+ +
+

Mission and Aims#

+

Computational models, based on detailed neuroanatomical and electrophysiological data, are heavily used as an aid for understanding the nervous system. +NeuroML is an international, collaborative initiative to develop a language for describing detailed models of neural systems, which will serve as a +standard data format for defining and exchanging descriptions of neuronal cell and network models.

+

NeuroML specifications are developed by the NeuroML Editorial Board and overseen by its Scientific Committee. +NeuroML is endorsed by the INCF, and is also an official COMBINE standard.

+

The NeuroML project community develops an XML (eXtensible Markup Language) based description language where XML Schemas are used to define model specifications. +The community also develops and maintains a number of libraries (in Python, Java and other languages) to facilitate use of these specifications.

+

The aims of the NeuroML initiative are:

+
    +
  • To create specifications for an XML-based language that describes the biophysics, anatomy and network architecture of neuronal systems at multiple scales

  • +
  • To facilitate the exchange of complex neuronal models between researchers, allowing for greater transparency and accessibility of models

  • +
  • To promote software tools which support NeuroML and support the development of new software and databases for neural modeling

  • +
  • To encourage researchers with models within the scope of NeuroML to exchange and publish their models in this format

  • +
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/MultiCompartmentOLMexample.html b/Userdocs/MultiCompartmentOLMexample.html new file mode 100644 index 00000000..29af217a --- /dev/null +++ b/Userdocs/MultiCompartmentOLMexample.html @@ -0,0 +1,1971 @@ + + + + + + + + + + + Simulating a multi compartment OLM neuron — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Simulating a multi compartment OLM neuron#

+

In this section we will model and simulate a multi-compartment Oriens-lacunosum moleculare (OLM) interneuron cell from the rodent hippocampal CA1 network model developed by Bezaire et al. ([BRB+16]). +The complete network model can be seen here on GitHub, and here on Open Source Brain.

+
+Morphology of constructed OLM cell in xy plane +
+

Fig. 22 Morphology of OLM cell in xy plane#

+
+
+
+Membrane potential for neuron recorded from the simulation at the soma +
+

Fig. 23 Membrane potential of the simulated OLM cell at the soma.#

+
+
+

This plot, saved as olm_example_sim_seg0_soma0-v.png is generated using the following Python NeuroML script:

+
#!/usr/bin/env python3
+"""
+Multi-compartmental OLM cell example
+
+File: olm-example.py
+
+Copyright 2023 NeuroML contributors
+Authors: Padraig Gleeson, Ankur Sinha
+"""
+
+import neuroml
+from neuroml import NeuroMLDocument
+from neuroml.utils import component_factory
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+from pyneuroml.plot.PlotMorphology import plot_2D
+import numpy as np
+
+
+def main():
+    """Main function
+
+    Include the NeuroML model into a LEMS simulation file, run it, plot some
+    data.
+    """
+    # Simulation bits
+    sim_id = "olm_example_sim"
+    simulation = LEMSSimulation(sim_id=sim_id, duration=600, dt=0.01, simulation_seed=123)
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_olm_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_olm_cell_network")
+
+    # Recording information from the simulation
+    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+    simulation.add_column_to_output_file("output0", column_id="pop0_0_v", quantity="pop0[0]/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_soma_0",
+                                         quantity="pop0/0/olm/0/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_soma_0",
+                                         quantity="pop0/0/olm/1/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_axon_0",
+                                         quantity="pop0/0/olm/2/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_axon_0",
+                                         quantity="pop0/0/olm/3/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_0",
+                                         quantity="pop0/0/olm/4/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_0",
+                                         quantity="pop0/0/olm/6/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_1",
+                                         quantity="pop0/0/olm/5/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_1",
+                                         quantity="pop0/0/olm/7/v")
+    # Save LEMS simulation to file
+    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the NEURON simulator
+    pynml.run_lems_with_jneuroml_neuron(sim_file, max_memory="2G", nogui=True,
+                                        plot=False, skip_run=False)
+    # Plot the data
+    plot_data(sim_id)
+
+
+def plot_data(sim_id):
+    """Plot the sim data.
+
+    Load the data from the file and plot the graph for the membrane potential
+    using the pynml generate_plot utility function.
+
+    :sim_id: ID of simulaton
+
+    """
+    data_array = np.loadtxt(sim_id + ".dat")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 1]], "Membrane potential (soma seg 0)", show_plot_already=False, save_figure_to=sim_id + "_seg0_soma0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 2]], "Membrane potential (soma seg 1)", show_plot_already=False, save_figure_to=sim_id + "_seg1_soma0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 3]], "Membrane potential (axon seg 0)", show_plot_already=False, save_figure_to=sim_id + "_seg0_axon0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 4]], "Membrane potential (axon seg 1)", show_plot_already=False, save_figure_to=sim_id + "_seg1_axon0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+
+
+def create_olm_network():
+    """Create the network
+
+    :returns: name of network nml file
+    """
+    net_doc = NeuroMLDocument(id="network",
+                              notes="OLM cell network")
+    net_doc_fn = "olm_example_net.nml"
+    net_doc.add("IncludeType", href=create_olm_cell())
+    net = net_doc.add("Network", id="single_olm_cell_network", validate=False)
+    # Create a population: convenient to create many cells of the same type
+    pop = net.add("Population", id="pop0", notes="A population for our cell",
+                  component="olm", size=1, type="populationList",
+                  validate=False)
+    pop.add("Instance", id=0, location=component_factory("Location", x=0., y=0., z=0.))
+    # Input
+    net_doc.add("PulseGenerator", id="pg_olm", notes="Simple pulse generator", delay="100ms", duration="100ms", amplitude="0.08nA")
+
+    net.add("ExplicitInput", target="pop0[0]", input="pg_olm")
+
+    pynml.write_neuroml2_file(nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True)
+    return net_doc_fn
+
+
+def create_olm_cell():
+    """Create the complete cell.
+
+    :returns: cell object
+    """
+    nml_cell_doc = component_factory("NeuroMLDocument", id="oml_cell")
+    cell = nml_cell_doc.add("Cell", id="olm", neuro_lex_id="NLXCELL:091206")  # type neuroml.Cell
+    nml_cell_file = cell.id + ".cell.nml"
+
+    cell.summary()
+    cell.info(show_contents=True)
+    cell.morphology.info(show_contents=True)
+
+    # Add two soma segments to an unbranched segment group
+    cell.add_unbranched_segment_group("soma_0")
+    diam = 10.0
+    soma_0 = cell.add_segment(
+        prox=[0.0, 0.0, 0.0, diam],
+        dist=[0.0, 10., 0.0, diam],
+        name="Seg0_soma_0",
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    soma_1 = cell.add_segment(
+        prox=None,
+        dist=[0.0, 10. + 10., 0.0, diam],
+        name="Seg1_soma_0",
+        parent=soma_0,
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    # Add axon segments
+    diam = 1.5
+    cell.add_unbranched_segments(
+        [
+            [0.0, 0.0, 0.0, diam],
+            [0.0, -75, 0.0, diam],
+            [0.0, -150, 0.0, diam],
+        ],
+        parent=soma_0,
+        fraction_along=0.0,
+        group_id="axon_0",
+        seg_type="axon"
+    )
+
+    # Add 2 dendrite segments, using the branching utility function
+
+    diam = 3.0
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [100, 120, 0.0, diam],
+            [177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_0",
+        seg_type="dendrite"
+    )
+
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [-100, 120, 0.0, diam],
+            [-177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_1",
+        seg_type="dendrite"
+    )
+
+    # color groups for morphology plots
+    den_seg_group = cell.get_segment_group("dendrite_group")
+    den_seg_group.add("Property", tag="color", value="0.8 0 0")
+
+    ax_seg_group = cell.get_segment_group("axon_group")
+    ax_seg_group.add("Property", tag="color", value="0 0.8 0")
+
+    soma_seg_group = cell.get_segment_group("soma_group")
+    soma_seg_group.add("Property", tag="color", value="0 0 0.8")
+
+    # Other cell properties
+    cell.set_init_memb_potential("-67mV")
+    cell.set_resistivity("0.15 kohm_cm")
+    cell.set_specific_capacitance("1.3 uF_per_cm2")
+
+    # channels
+    # leak
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="leak_all",
+                             cond_density="0.01 mS_per_cm2",
+                             ion_channel="leak_chan",
+                             ion_chan_def_file="olm-example/leak_chan.channel.nml",
+                             erev="-67mV",
+                             ion="non_specific")
+    # HCNolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="HCNolm_soma",
+                             cond_density="0.5 mS_per_cm2",
+                             ion_channel="HCNolm",
+                             ion_chan_def_file="olm-example/HCNolm.channel.nml",
+                             erev="-32.9mV",
+                             ion="h",
+                             group_id="soma_group")
+    # Kdrfast_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_soma",
+                             cond_density="73.37 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # Kdrfast_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_dendrite",
+                             cond_density="105.8 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Kdrfast_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_axon",
+                             cond_density="117.392 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="axon_group")
+    # KvAolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_soma",
+                             cond_density="4.95 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # KvAolm_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_dendrite",
+                             cond_density="2.8 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Nav_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_soma",
+                             cond_density="10.7 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="soma_group")
+    # Nav_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_dendrite",
+                             cond_density="23.4 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="dendrite_group")
+    # Nav_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_axon",
+                             cond_density="17.12 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="axon_group")
+
+    cell.optimise_segment_groups()
+    cell.validate(recursive=True)
+    pynml.write_neuroml2_file(nml_cell_doc, nml_cell_file, True, True)
+    plot_2D(nml_cell_file, plane2d="xy", nogui=True,
+            save_to_file="olm.cell.xy.png")
+    return nml_cell_file
+
+
+if __name__ == "__main__":
+    main()
+
+
+
+

Declaring the model in NeuroML#

+

Similar to previous examples, we will first declare the model, visualise it, and then simulate it. +The OLM model is slightly more complex than the HH neuron model we had worked with in the previous tutorial since it includes multiple compartments. +However, where we had declared the ion-channels ourselves in the previous example, here will will not do so. +We will include channels that have been pre-defined in NeuroML to demonstrate how components defined in NeuroML can be easily re-used in models.

+

We will follow the same method as before. +We will first define the cell, create a network with one instance of the cell, and then simulate it to record and plot the membrane potential from different segments.

+
+

Declaring the cell#

+

To keep our Python script modularised, we start constructing our cell in a separate function.

+
def create_olm_cell():
+    """Create the complete cell.
+
+    :returns: cell object
+    """
+    nml_cell_doc = component_factory("NeuroMLDocument", id="oml_cell")
+    cell = nml_cell_doc.add("Cell", id="olm", neuro_lex_id="NLXCELL:091206")  # type neuroml.Cell
+    nml_cell_file = cell.id + ".cell.nml"
+
+    cell.summary()
+    cell.info(show_contents=True)
+    cell.morphology.info(show_contents=True)
+
+    # Add two soma segments to an unbranched segment group
+    cell.add_unbranched_segment_group("soma_0")
+    diam = 10.0
+    soma_0 = cell.add_segment(
+        prox=[0.0, 0.0, 0.0, diam],
+        dist=[0.0, 10., 0.0, diam],
+        name="Seg0_soma_0",
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    soma_1 = cell.add_segment(
+        prox=None,
+        dist=[0.0, 10. + 10., 0.0, diam],
+        name="Seg1_soma_0",
+        parent=soma_0,
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    # Add axon segments
+    diam = 1.5
+    cell.add_unbranched_segments(
+        [
+            [0.0, 0.0, 0.0, diam],
+            [0.0, -75, 0.0, diam],
+            [0.0, -150, 0.0, diam],
+        ],
+        parent=soma_0,
+        fraction_along=0.0,
+        group_id="axon_0",
+        seg_type="axon"
+    )
+
+    # Add 2 dendrite segments, using the branching utility function
+
+    diam = 3.0
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [100, 120, 0.0, diam],
+            [177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_0",
+        seg_type="dendrite"
+    )
+
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [-100, 120, 0.0, diam],
+            [-177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_1",
+        seg_type="dendrite"
+    )
+
+    # color groups for morphology plots
+    den_seg_group = cell.get_segment_group("dendrite_group")
+    den_seg_group.add("Property", tag="color", value="0.8 0 0")
+
+    ax_seg_group = cell.get_segment_group("axon_group")
+    ax_seg_group.add("Property", tag="color", value="0 0.8 0")
+
+    soma_seg_group = cell.get_segment_group("soma_group")
+    soma_seg_group.add("Property", tag="color", value="0 0 0.8")
+
+    # Other cell properties
+    cell.set_init_memb_potential("-67mV")
+    cell.set_resistivity("0.15 kohm_cm")
+    cell.set_specific_capacitance("1.3 uF_per_cm2")
+
+    # channels
+    # leak
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="leak_all",
+                             cond_density="0.01 mS_per_cm2",
+                             ion_channel="leak_chan",
+                             ion_chan_def_file="olm-example/leak_chan.channel.nml",
+                             erev="-67mV",
+                             ion="non_specific")
+    # HCNolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="HCNolm_soma",
+                             cond_density="0.5 mS_per_cm2",
+                             ion_channel="HCNolm",
+                             ion_chan_def_file="olm-example/HCNolm.channel.nml",
+                             erev="-32.9mV",
+                             ion="h",
+                             group_id="soma_group")
+    # Kdrfast_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_soma",
+                             cond_density="73.37 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # Kdrfast_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_dendrite",
+                             cond_density="105.8 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Kdrfast_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_axon",
+                             cond_density="117.392 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="axon_group")
+    # KvAolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_soma",
+                             cond_density="4.95 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # KvAolm_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_dendrite",
+                             cond_density="2.8 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Nav_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_soma",
+                             cond_density="10.7 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="soma_group")
+    # Nav_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_dendrite",
+                             cond_density="23.4 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="dendrite_group")
+    # Nav_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_axon",
+                             cond_density="17.12 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="axon_group")
+
+
+
+

Let us walk through this function:

+
    nml_cell_doc = component_factory("NeuroMLDocument", id="oml_cell")
+    cell = nml_cell_doc.add("Cell", id="olm", neuro_lex_id="NLXCELL:091206")  # type neuroml.Cell
+    nml_cell_file = cell.id + ".cell.nml"
+
+    cell.summary()
+    cell.info(show_contents=True)
+    cell.morphology.info(show_contents=True)
+
+
+
+

We create a new model document that will hold the cell model. +Then, we create and add a new Cell using the add method to the document. +We also provide a neuro_lex_id here, which is the NeuroLex ontology identifier. +This allows us to better connect models to biological concepts.

+

As we have seen in the single Izhikevich neuron example, the add method calls the component_factory to create the component object for us. +For the Cell component type, it does a number of extra things for us to set up, or initialise, the cell.

+

We have a number of ways of inspecting the cell. +The summary function provides a very short summary of the cell. +This is useful to quickly get a high level overview of it:

+
>>> cell.summary()
+*******************************************************
+* Cell: olm
+* Notes: None
+* Segments: 0
+* SegmentGroups: 4
+*******************************************************
+
+
+

We can also use the general info function to inspect the cell:

+
>>> cell.info(show_contents=True)
+Cell -- Cell with  **segment** s specified in a  **morphology**  element along with details on its  **biophysicalProperties** . NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v**  of this cell represents the membrane potential in that isopotential segment.
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Cell are:
+* biophysical_properties_attr (class: NmlId, Optional)
+* morphology (class: Morphology, Optional)
+        * Contents ('ids'/<objects>): 'morphology'
+
+* neuro_lex_id (class: NeuroLexId, Optional)
+        * Contents ('ids'/<objects>): NLXCELL:091206
+
+* metaid (class: MetaId, Optional)
+* biophysical_properties (class: BiophysicalProperties, Optional)
+        * Contents ('ids'/<objects>): 'biophys'
+
+* id (class: NmlId, Required)
+        * Contents ('ids'/<objects>): olm
+
+* notes (class: xs:string, Optional)
+* properties (class: Property, Optional)
+* annotation (class: Annotation, Optional)
+* morphology_attr (class: NmlId, Optional)
+
+
+
+

We see the cell already contains biophysical_properties or morphology. +Because these are components of the cell that are expected to be used, these were added automatically for us when the new component was created.

+

Let us take a look at the morphology of the cell:

+
>>> cell.morphology.info(show_contents=True)
+Morphology -- The collection of  **segment** s which specify the 3D structure of the cell, along with a number of  **segmentGroup** s
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Morphology are:
+* segments (class: Segment, Required)
+* metaid (class: MetaId, Optional)
+* segment_groups (class: SegmentGroup, Optional)
+        * Contents ('ids'/<objects>): ['all', 'soma_group', 'axon_group', 'dendrite_group']
+
+* id (class: NmlId, Required)
+        * Contents ('ids'/<objects>): morphology
+
+* notes (class: xs:string, Optional)
+* properties (class: Property, Optional)
+* annotation (class: Annotation, Optional)
+
+
+

We see that there are no segments in the cell because we have not added any. +However, there are already a number of “default” segment groups that were automatically added for us: all, soma_group, axon_group, dendrite_group. +These groups allow us to keep track of all the segments, and of the segments forming the soma, the axon, and the dendrites of the cell respectively. +Take a look at the conventions page for more information on these.

+

We now have an empty cell. +Since we are building a multi-compartmental cell, we now proceed to define the detailed morphology of the cell. +We do this by adding segments and grouping them in to segment groups. +We can add segments using the add_segment utility function, as we do for the segments forming the soma. +Here, our soma has two segments.

+

+    # Add two soma segments to an unbranched segment group
+    cell.add_unbranched_segment_group("soma_0")
+    diam = 10.0
+    soma_0 = cell.add_segment(
+        prox=[0.0, 0.0, 0.0, diam],
+        dist=[0.0, 10., 0.0, diam],
+        name="Seg0_soma_0",
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    soma_1 = cell.add_segment(
+        prox=None,
+        dist=[0.0, 10. + 10., 0.0, diam],
+        name="Seg1_soma_0",
+        parent=soma_0,
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+
+

The utility function takes the dimensions of the segment—it’s proximal and distal co-ordinates and the diameter to create a segment of the provided name. +Additionally, since segments need to be contiguous, it makes the first segment the parent of the second, to build a chain. +Finally, it places the segment into the specified segment group and the default groups that we also have and adds the segment to the cell’s morphology.

+

Note that by default, the add_segment function does not know if the segments are contiguous, i.e., that they form an unbranched branch of the cell. +We could have added segments here that do not line up in a chain, when building different parts of a cell for example. +In this case, we know that the two soma segments must be contiguous, and that they are on the same unbranched branch (i.e. a continuous section without any branching points on it), so we create an unbranched segment group first using the add_unbranched_segment_group.

+

If we were only creating cell morphologies, this would not not matter much. +Even if the two segments were not included in a group of unbranched segments, they would still be connected. +However, for simulation, simulators such as NEURON need to know which parts of the cell form unbranched sections so that they can apply the cable equation and break them into smaller segments to simulate the electric current through them. +(See [CGH+07] for more information on how different simulators simulate cells with detailed morphologies.)

+

Next, we can call the same functions multiple times to add soma, dendritic, and axonal segments to our cell but this can get quite lengthy. +To easily add unbranched contiguous lists of segments to the cell, we can directly use the add_unbranched_segments utility function. +Here we use it to create an axonal segment group, and two dendritic groups each with two segments. +The first point we provide is the proximal (starting) of the dendrite. +The next two points are the distal (ends) of each segment forming the section.

+
    # Add axon segments
+    diam = 1.5
+    cell.add_unbranched_segments(
+        [
+            [0.0, 0.0, 0.0, diam],
+            [0.0, -75, 0.0, diam],
+            [0.0, -150, 0.0, diam],
+        ],
+        parent=soma_0,
+        fraction_along=0.0,
+        group_id="axon_0",
+        seg_type="axon"
+    )
+
+    # Add 2 dendrite segments, using the branching utility function
+
+    diam = 3.0
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [100, 120, 0.0, diam],
+            [177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_0",
+        seg_type="dendrite"
+    )
+
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [-100, 120, 0.0, diam],
+            [-177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_1",
+        seg_type="dendrite"
+    )
+
+
+

We repeat this process to create more dendritic and axonal sections of contiguous segments.

+

Finally, we add an extra colour property to the three primary segment groups that can be used when generating morphology graphs:

+
    # color groups for morphology plots
+    den_seg_group = cell.get_segment_group("dendrite_group")
+    den_seg_group.add("Property", tag="color", value="0.8 0 0")
+
+    ax_seg_group = cell.get_segment_group("axon_group")
+    ax_seg_group.add("Property", tag="color", value="0 0.8 0")
+
+    soma_seg_group = cell.get_segment_group("soma_group")
+    soma_seg_group.add("Property", tag="color", value="0 0 0.8")
+
+
+

We have now completed adding the morphological information to our cell. +Next, we proceed to our biophysical properties, e.g.:

+ +

We use more helpful utility functions to set these values

+
    # Other cell properties
+    cell.set_init_memb_potential("-67mV")
+    cell.set_resistivity("0.15 kohm_cm")
+    cell.set_specific_capacitance("1.3 uF_per_cm2")
+
+
+

For setting channel densities, we have the add_channel_density function:

+
    # channels
+    # leak
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="leak_all",
+                             cond_density="0.01 mS_per_cm2",
+                             ion_channel="leak_chan",
+                             ion_chan_def_file="olm-example/leak_chan.channel.nml",
+                             erev="-67mV",
+                             ion="non_specific")
+    # HCNolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="HCNolm_soma",
+                             cond_density="0.5 mS_per_cm2",
+                             ion_channel="HCNolm",
+                             ion_chan_def_file="olm-example/HCNolm.channel.nml",
+                             erev="-32.9mV",
+                             ion="h",
+                             group_id="soma_group")
+    # Kdrfast_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_soma",
+                             cond_density="73.37 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # Kdrfast_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_dendrite",
+                             cond_density="105.8 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Kdrfast_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_axon",
+                             cond_density="117.392 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="axon_group")
+    # KvAolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_soma",
+                             cond_density="4.95 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # KvAolm_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_dendrite",
+                             cond_density="2.8 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Nav_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_soma",
+                             cond_density="10.7 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="soma_group")
+    # Nav_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_dendrite",
+                             cond_density="23.4 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="dendrite_group")
+    # Nav_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_axon",
+                             cond_density="17.12 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="axon_group")
+
+
+

Note that we are not writing our channel files from scratch here. +We are re-using already written NeuroML channel definitions by simply including their NeuroML definition files.

+

This completes the definition of our cell. +We now run the level one validation, write it to a file while also running a complete (level one and level two) validation using pyNeuroML. +We also generate the morphology plot shown on the top of this page.

+
    cell.optimise_segment_groups()
+    cell.validate(recursive=True)
+    pynml.write_neuroml2_file(nml_cell_doc, nml_cell_file, True, True)
+    plot_2D(nml_cell_file, plane2d="xy", nogui=True,
+
+
+

The resulting NeuroML file is:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="oml_cell">
+    <include href="olm-example/leak_chan.channel.nml"/>
+    <include href="olm-example/HCNolm.channel.nml"/>
+    <include href="olm-example/Kdrfast.channel.nml"/>
+    <include href="olm-example/KvAolm.channel.nml"/>
+    <include href="olm-example/Nav.channel.nml"/>
+    <cell id="olm" neuroLexId="NLXCELL:091206">
+        <morphology id="morphology">
+            <segment id="0" name="Seg0_soma_0">
+                <proximal x="0.0" y="0.0" z="0.0" diameter="10.0"/>
+                <distal x="0.0" y="10.0" z="0.0" diameter="10.0"/>
+            </segment>
+            <segment id="1" name="Seg1_soma_0">
+                <parent segment="0"/>
+                <distal x="0.0" y="20.0" z="0.0" diameter="10.0"/>
+            </segment>
+            <segment id="2" name="Seg0_axon_0">
+                <parent segment="0" fractionAlong="0.0"/>
+                <proximal x="0.0" y="0.0" z="0.0" diameter="1.5"/>
+                <distal x="0.0" y="-75.0" z="0.0" diameter="1.5"/>
+            </segment>
+            <segment id="3" name="Seg1_axon_0">
+                <parent segment="2"/>
+                <proximal x="0.0" y="-75.0" z="0.0" diameter="1.5"/>
+                <distal x="0.0" y="-150.0" z="0.0" diameter="1.5"/>
+            </segment>
+            <segment id="4" name="Seg0_dend_0">
+                <parent segment="1"/>
+                <proximal x="0.0" y="20.0" z="0.0" diameter="3.0"/>
+                <distal x="100.0" y="120.0" z="0.0" diameter="3.0"/>
+            </segment>
+            <segment id="5" name="Seg1_dend_0">
+                <parent segment="4"/>
+                <proximal x="100.0" y="120.0" z="0.0" diameter="3.0"/>
+                <distal x="177.0" y="197.0" z="0.0" diameter="3.0"/>
+            </segment>
+            <segment id="6" name="Seg0_dend_1">
+                <parent segment="1"/>
+                <proximal x="0.0" y="20.0" z="0.0" diameter="3.0"/>
+                <distal x="-100.0" y="120.0" z="0.0" diameter="3.0"/>
+            </segment>
+            <segment id="7" name="Seg1_dend_1">
+                <parent segment="6"/>
+                <proximal x="-100.0" y="120.0" z="0.0" diameter="3.0"/>
+                <distal x="-177.0" y="197.0" z="0.0" diameter="3.0"/>
+            </segment>
+            <segmentGroup id="soma_0" neuroLexId="sao864921383">
+                <member segment="0"/>
+                <member segment="1"/>
+            </segmentGroup>
+            <segmentGroup id="axon_0" neuroLexId="sao864921383">
+                <member segment="2"/>
+                <member segment="3"/>
+            </segmentGroup>
+            <segmentGroup id="dend_0" neuroLexId="sao864921383">
+                <member segment="4"/>
+                <member segment="5"/>
+            </segmentGroup>
+            <segmentGroup id="dend_1" neuroLexId="sao864921383">
+                <member segment="6"/>
+                <member segment="7"/>
+            </segmentGroup>
+            <segmentGroup id="soma_group" neuroLexId="GO:0043025">
+                <notes>Default soma segment group for the cell</notes>
+                <property tag="color" value="0 0 0.8"/>
+                <include segmentGroup="soma_0"/>
+            </segmentGroup>
+            <segmentGroup id="axon_group" neuroLexId="GO:0030424">
+                <notes>Default axon segment group for the cell</notes>
+                <property tag="color" value="0 0.8 0"/>
+                <include segmentGroup="axon_0"/>
+            </segmentGroup>
+            <segmentGroup id="dendrite_group" neuroLexId="GO:0030425">
+                <notes>Default dendrite segment group for the cell</notes>
+                <property tag="color" value="0.8 0 0"/>
+                <include segmentGroup="dend_0"/>
+                <include segmentGroup="dend_1"/>
+            </segmentGroup>
+            <segmentGroup id="all">
+                <notes>Default segment group for all segments in the cell</notes>
+                <include segmentGroup="axon_0"/>
+                <include segmentGroup="dend_0"/>
+                <include segmentGroup="dend_1"/>
+                <include segmentGroup="soma_0"/>
+            </segmentGroup>
+        </morphology>
+        <biophysicalProperties id="biophys">
+            <membraneProperties>
+                <channelDensity id="leak_all" ionChannel="leak_chan" condDensity="0.01 mS_per_cm2" erev="-67mV" ion="non_specific"/>
+                <channelDensity id="HCNolm_soma" ionChannel="HCNolm" condDensity="0.5 mS_per_cm2" erev="-32.9mV" segmentGroup="soma_group" ion="h"/>
+                <channelDensity id="Kdrfast_soma" ionChannel="Kdrfast" condDensity="73.37 mS_per_cm2" erev="-77mV" segmentGroup="soma_group" ion="k"/>
+                <channelDensity id="Kdrfast_dendrite" ionChannel="Kdrfast" condDensity="105.8 mS_per_cm2" erev="-77mV" segmentGroup="dendrite_group" ion="k"/>
+                <channelDensity id="Kdrfast_axon" ionChannel="Kdrfast" condDensity="117.392 mS_per_cm2" erev="-77mV" segmentGroup="axon_group" ion="k"/>
+                <channelDensity id="KvAolm_soma" ionChannel="KvAolm" condDensity="4.95 mS_per_cm2" erev="-77mV" segmentGroup="soma_group" ion="k"/>
+                <channelDensity id="KvAolm_dendrite" ionChannel="KvAolm" condDensity="2.8 mS_per_cm2" erev="-77mV" segmentGroup="dendrite_group" ion="k"/>
+                <channelDensity id="Nav_soma" ionChannel="Nav" condDensity="10.7 mS_per_cm2" erev="50mV" segmentGroup="soma_group" ion="na"/>
+                <channelDensity id="Nav_dendrite" ionChannel="Nav" condDensity="23.4 mS_per_cm2" erev="50mV" segmentGroup="dendrite_group" ion="na"/>
+                <channelDensity id="Nav_axon" ionChannel="Nav" condDensity="17.12 mS_per_cm2" erev="50mV" segmentGroup="axon_group" ion="na"/>
+                <specificCapacitance value="1.3 uF_per_cm2"/>
+                <initMembPotential value="-67mV"/>
+            </membraneProperties>
+            <intracellularProperties>
+                <resistivity value="0.15 kohm_cm"/>
+            </intracellularProperties>
+        </biophysicalProperties>
+    </cell>
+</neuroml>
+
+
+

We can now already inspect our cell using the NeuroML tools. +We have already generated the morphology plot in our script, but we can also do it using pynml:

+
pynml -png olm.cell.png
+...
+pyNeuroML >>> Writing to: /home/asinha/Documents/02_Code/00_mine/2020-OSB/NeuroML-Documentation/source/Userdocs/NML2_examples/olm.cell.png
+
+
+

This gives us a figure of the morphology of our cell, similar to the one we’ve already generated:

+
+Figure showing the morphology of the OLM cell generated from the NeuroML definition. +
+

Fig. 24 Figure showing the morphology of the OLM cell generated from the NeuroML definition.#

+
+
+
+
+

Declaring the network#

+

We now use our cell in a network. +Similar to our previous example, we are going to only create a network with one cell, and an explicit input to the cell:

+
def create_olm_network():
+    """Create the network
+
+    :returns: name of network nml file
+    """
+    net_doc = NeuroMLDocument(id="network",
+                              notes="OLM cell network")
+    net_doc_fn = "olm_example_net.nml"
+    net_doc.add("IncludeType", href=create_olm_cell())
+    net = net_doc.add("Network", id="single_olm_cell_network", validate=False)
+    # Create a population: convenient to create many cells of the same type
+    pop = net.add("Population", id="pop0", notes="A population for our cell",
+                  component="olm", size=1, type="populationList",
+                  validate=False)
+    pop.add("Instance", id=0, location=component_factory("Location", x=0., y=0., z=0.))
+    # Input
+    net_doc.add("PulseGenerator", id="pg_olm", notes="Simple pulse generator", delay="100ms", duration="100ms", amplitude="0.08nA")
+
+    net.add("ExplicitInput", target="pop0[0]", input="pg_olm")
+
+    pynml.write_neuroml2_file(nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True)
+    return net_doc_fn
+
+
+
+

We start in the same way, by creating a new NeuroML document and including our cell file into it. +We then create a population comprising of a single cell. +We create a pulse generator as an explicit input, which targets our population. +Note that as the schema documentation for ExplicitInput notes, any current source (any component that extends basePointCurrent) can be used as an ExplicitInput.

+

We add all of these to the network and save (and validate) our network file. +The NeuroML file generated is below:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="network">
+    <notes>OLM cell network</notes>
+    <include href="olm.cell.nml"/>
+    <pulseGenerator id="pg_olm" delay="100ms" duration="100ms" amplitude="0.08nA">
+        <notes>Simple pulse generator</notes>
+    </pulseGenerator>
+    <network id="single_olm_cell_network">
+        <population id="pop0" component="olm" size="1" type="populationList">
+            <notes>A population for our cell</notes>
+            <instance id="0">
+                <location x="0.0" y="0.0" z="0.0"/>
+            </instance>
+        </population>
+        <explicitInput target="pop0[0]" input="pg_olm"/>
+    </network>
+</neuroml>
+
+
+
+
+

The generated NeuroML model#

+

Before we look at simulating the model, we can inspect our model to check for correctness. +All our NeuroML files were validated when they were created already, so we do not need to run this step again. +However, if required, this can be easily done:

+
pynml -validate olm*nml
+
+
+

Next, we can visualise our model using the information noted in the visualising NeuroML models page (including the -v verbose option for more information on the cell):

+
pynml-summary olm_example_net.nml -v
+*******************************************************
+* NeuroMLDocument: network
+*
+*  ComponentType: ['Bezaire_HCNolm_tau', 'Bezaire_Kdrfast_betaq', 'Bezaire_KvAolm_taub', 'Bezaire_Nav_alphah']
+*  IonChannel: ['HCNolm', 'Kdrfast', 'KvAolm', 'Nav', 'leak_chan']
+*  PulseGenerator: ['pg_olm']
+*
+*  Cell: olm
+*    <Segment|0|Seg0_soma_0>
+*      Parent segment: None (root segment)
+*      (0.0, 0.0, 0.0), diam 10.0um -> (0.0, 10.0, 0.0), diam 10.0um; seg length: 10.0 um
+*      Surface area: 314.1592653589793 um2, volume: 785.3981633974482 um3
+*    <Segment|1|Seg1_soma_0>
+*      Parent segment: 0
+*      None -> (0.0, 20.0, 0.0), diam 10.0um; seg length: 10.0 um
+*      Surface area: 314.1592653589793 um2, volume: 785.3981633974482 um3
+*    <Segment|2|Seg0_axon_0>
+*      Parent segment: 0
+*      (0.0, 0.0, 0.0), diam 1.5um -> (0.0, -75.0, 0.0), diam 1.5um; seg length: 75.0 um
+*      Surface area: 353.4291735288517 um2, volume: 132.53594007331938 um3
+*    <Segment|3|Seg1_axon_0>
+*      Parent segment: 2
+*      None -> (0.0, -150.0, 0.0), diam 1.5um; seg length: 75.0 um
+*      Surface area: 353.4291735288517 um2, volume: 132.53594007331938 um3
+*    <Segment|4|Seg0_dend_0>
+*      Parent segment: 1
+*      (0.0, 20.0, 0.0), diam 3.0um -> (100.0, 120.0, 0.0), diam 3.0um; seg length: 141.4213562373095 um
+*      Surface area: 1332.8648814475098 um2, volume: 999.6486610856323 um3
+*    <Segment|5|Seg1_dend_0>
+*      Parent segment: 4
+*      None -> (177.0, 197.0, 0.0), diam 3.0um; seg length: 108.89444430272832 um
+*      Surface area: 1026.3059587145826 um2, volume: 769.7294690359369 um3
+*    <Segment|6|Seg0_dend_1>
+*      Parent segment: 1
+*      (0.0, 20.0, 0.0), diam 3.0um -> (-100.0, 120.0, 0.0), diam 3.0um; seg length: 141.4213562373095 um
+*      Surface area: 1332.8648814475098 um2, volume: 999.6486610856323 um3
+*    <Segment|7|Seg1_dend_1>
+*      Parent segment: 6
+*      None -> (-177.0, 197.0, 0.0), diam 3.0um; seg length: 108.89444430272832 um
+*      Surface area: 1026.3059587145826 um2, volume: 769.7294690359369 um3
+*    Total length of 8 segments: 670.6316010800756 um; total area: 6053.518558099847 um2
+*
+*    SegmentGroup: all, 8 member(s),    0 included group(s);    contains 8 segments in total
+*    SegmentGroup: soma_group,  2 member(s),    1 included group(s);   contains 2 segments in total
+*    SegmentGroup: axon_group,  2 member(s),    1 included group(s);   contains 2 segments in total
+*    SegmentGroup: dendrite_group,      4 member(s),    2 included group(s);    contains 4 segments in total
+*    SegmentGroup: soma_0,      2 member(s),    0 included group(s);   contains 2 segments in total
+*    SegmentGroup: axon_0,      2 member(s),    0 included group(s);   contains 2 segments in total
+*    SegmentGroup: dend_0,      2 member(s),    0 included group(s);   contains 2 segments in total
+*    SegmentGroup: dend_1,      2 member(s),    0 included group(s);   contains 2 segments in total
+*
+*    Channel density: leak_all on all;  conductance of 0.01 mS_per_cm2 through ion chan leak_chan with ion non_specific, erev: -67mV
+*      Channel is on <Segment|0|Seg0_soma_0>,   total conductance: 0.1 S_per_m2 x 3.1415926535897934e-10 m2 = 3.1415926535897936e-11 S (31.41592653589794 pS)
+*      Channel is on <Segment|1|Seg1_soma_0>,   total conductance: 0.1 S_per_m2 x 3.1415926535897934e-10 m2 = 3.1415926535897936e-11 S (31.41592653589794 pS)
+*      Channel is on <Segment|2|Seg0_axon_0>,   total conductance: 0.1 S_per_m2 x 3.534291735288517e-10 m2 = 3.534291735288518e-11 S (35.34291735288518 pS)
+*      Channel is on <Segment|3|Seg1_axon_0>,   total conductance: 0.1 S_per_m2 x 3.534291735288517e-10 m2 = 3.534291735288518e-11 S (35.34291735288518 pS)
+*      Channel is on <Segment|4|Seg0_dend_0>,   total conductance: 0.1 S_per_m2 x 1.3328648814475097e-09 m2 = 1.3328648814475097e-10 S (133.28648814475096 pS)
+*      Channel is on <Segment|5|Seg1_dend_0>,   total conductance: 0.1 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0263059587145826e-10 S (102.63059587145825 pS)
+*      Channel is on <Segment|6|Seg0_dend_1>,   total conductance: 0.1 S_per_m2 x 1.3328648814475097e-09 m2 = 1.3328648814475097e-10 S (133.28648814475096 pS)
+*      Channel is on <Segment|7|Seg1_dend_1>,   total conductance: 0.1 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0263059587145826e-10 S (102.63059587145825 pS)
+*    Channel density: HCNolm_soma on soma_group;        conductance of 0.5 mS_per_cm2 through ion chan HCNolm with ion h, erev: -32.9mV
+*      Channel is on <Segment|0|Seg0_soma_0>,   total conductance: 5.0 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5707963267948968e-09 S (1570.796326794897 pS)
+*      Channel is on <Segment|1|Seg1_soma_0>,   total conductance: 5.0 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5707963267948968e-09 S (1570.796326794897 pS)
+*    Channel density: Kdrfast_soma on soma_group;       conductance of 73.37 mS_per_cm2 through ion chan Kdrfast with ion k, erev: -77mV
+*      Channel is on <Segment|0|Seg0_soma_0>,   total conductance: 733.7 S_per_m2 x 3.1415926535897934e-10 m2 = 2.3049865299388314e-07 S (230498.65299388315 pS)
+*      Channel is on <Segment|1|Seg1_soma_0>,   total conductance: 733.7 S_per_m2 x 3.1415926535897934e-10 m2 = 2.3049865299388314e-07 S (230498.65299388315 pS)
+*    Channel density: Kdrfast_dendrite on dendrite_group;       conductance of 105.8 mS_per_cm2 through ion chan Kdrfast with ion k, erev: -77mV
+*      Channel is on <Segment|4|Seg0_dend_0>,   total conductance: 1058.0 S_per_m2 x 1.3328648814475097e-09 m2 = 1.4101710445714652e-06 S (1410171.0445714653 pS)
+*      Channel is on <Segment|5|Seg1_dend_0>,   total conductance: 1058.0 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0858317043200284e-06 S (1085831.7043200284 pS)
+*      Channel is on <Segment|6|Seg0_dend_1>,   total conductance: 1058.0 S_per_m2 x 1.3328648814475097e-09 m2 = 1.4101710445714652e-06 S (1410171.0445714653 pS)
+*      Channel is on <Segment|7|Seg1_dend_1>,   total conductance: 1058.0 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0858317043200284e-06 S (1085831.7043200284 pS)
+*    Channel density: Kdrfast_axon on axon_group;       conductance of 117.392 mS_per_cm2 through ion chan Kdrfast with ion k, erev: -77mV
+*      Channel is on <Segment|2|Seg0_axon_0>,   total conductance: 1173.92 S_per_m2 x 3.534291735288517e-10 m2 = 4.1489757538898964e-07 S (414897.57538898964 pS)
+*      Channel is on <Segment|3|Seg1_axon_0>,   total conductance: 1173.92 S_per_m2 x 3.534291735288517e-10 m2 = 4.1489757538898964e-07 S (414897.57538898964 pS)
+*    Channel density: KvAolm_soma on soma_group;        conductance of 4.95 mS_per_cm2 through ion chan KvAolm with ion k, erev: -77mV
+*      Channel is on <Segment|0|Seg0_soma_0>,   total conductance: 49.5 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5550883635269477e-08 S (15550.883635269476 pS)
+*      Channel is on <Segment|1|Seg1_soma_0>,   total conductance: 49.5 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5550883635269477e-08 S (15550.883635269476 pS)
+*    Channel density: KvAolm_dendrite on dendrite_group;        conductance of 2.8 mS_per_cm2 through ion chan KvAolm with ion k, erev: -77mV
+*      Channel is on <Segment|4|Seg0_dend_0>,   total conductance: 28.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.7320216680530273e-08 S (37320.21668053028 pS)
+*      Channel is on <Segment|5|Seg1_dend_0>,   total conductance: 28.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.8736566844008313e-08 S (28736.566844008314 pS)
+*      Channel is on <Segment|6|Seg0_dend_1>,   total conductance: 28.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.7320216680530273e-08 S (37320.21668053028 pS)
+*      Channel is on <Segment|7|Seg1_dend_1>,   total conductance: 28.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.8736566844008313e-08 S (28736.566844008314 pS)
+*    Channel density: Nav_soma on soma_group;   conductance of 10.7 mS_per_cm2 through ion chan Nav with ion na, erev: 50mV
+*      Channel is on <Segment|0|Seg0_soma_0>,   total conductance: 107.0 S_per_m2 x 3.1415926535897934e-10 m2 = 3.361504139341079e-08 S (33615.04139341079 pS)
+*      Channel is on <Segment|1|Seg1_soma_0>,   total conductance: 107.0 S_per_m2 x 3.1415926535897934e-10 m2 = 3.361504139341079e-08 S (33615.04139341079 pS)
+*    Channel density: Nav_dendrite on dendrite_group;   conductance of 23.4 mS_per_cm2 through ion chan Nav with ion na, erev: 50mV
+*      Channel is on <Segment|4|Seg0_dend_0>,   total conductance: 234.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.118903822587173e-07 S (311890.3822587173 pS)
+*      Channel is on <Segment|5|Seg1_dend_0>,   total conductance: 234.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.401555943392123e-07 S (240155.59433921232 pS)
+*      Channel is on <Segment|6|Seg0_dend_1>,   total conductance: 234.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.118903822587173e-07 S (311890.3822587173 pS)
+*      Channel is on <Segment|7|Seg1_dend_1>,   total conductance: 234.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.401555943392123e-07 S (240155.59433921232 pS)
+*    Channel density: Nav_axon on axon_group;   conductance of 17.12 mS_per_cm2 through ion chan Nav with ion na, erev: 50mV
+*      Channel is on <Segment|2|Seg0_axon_0>,   total conductance: 171.20000000000002 S_per_m2 x 3.534291735288517e-10 m2 = 6.050707450813942e-08 S (60507.07450813943 pS)
+*      Channel is on <Segment|3|Seg1_axon_0>,   total conductance: 171.20000000000002 S_per_m2 x 3.534291735288517e-10 m2 = 6.050707450813942e-08 S (60507.07450813943 pS)
+*
+*    Specific capacitance on all: 1.3 uF_per_cm2
+*      Capacitance of <Segment|0|Seg0_soma_0>,  total capacitance: 0.013000000000000001 F_per_m2 x 3.1415926535897934e-10 m2 = 4.084070449666732e-12 F (4.084070449666732 pF)
+*      Capacitance of <Segment|1|Seg1_soma_0>,  total capacitance: 0.013000000000000001 F_per_m2 x 3.1415926535897934e-10 m2 = 4.084070449666732e-12 F (4.084070449666732 pF)
+*      Capacitance of <Segment|2|Seg0_axon_0>,  total capacitance: 0.013000000000000001 F_per_m2 x 3.534291735288517e-10 m2 = 4.594579255875073e-12 F (4.594579255875073 pF)
+*      Capacitance of <Segment|3|Seg1_axon_0>,  total capacitance: 0.013000000000000001 F_per_m2 x 3.534291735288517e-10 m2 = 4.594579255875073e-12 F (4.594579255875073 pF)
+*      Capacitance of <Segment|4|Seg0_dend_0>,  total capacitance: 0.013000000000000001 F_per_m2 x 1.3328648814475097e-09 m2 = 1.732724345881763e-11 F (17.32724345881763 pF)
+*      Capacitance of <Segment|5|Seg1_dend_0>,  total capacitance: 0.013000000000000001 F_per_m2 x 1.0263059587145826e-09 m2 = 1.3341977463289574e-11 F (13.341977463289574 pF)
+*      Capacitance of <Segment|6|Seg0_dend_1>,  total capacitance: 0.013000000000000001 F_per_m2 x 1.3328648814475097e-09 m2 = 1.732724345881763e-11 F (17.32724345881763 pF)
+*      Capacitance of <Segment|7|Seg1_dend_1>,  total capacitance: 0.013000000000000001 F_per_m2 x 1.0263059587145826e-09 m2 = 1.3341977463289574e-11 F (13.341977463289574 pF)
+*
+*  Network: single_olm_cell_network
+*
+*   1 cells in 1 populations
+*     Population: pop0 with 1 components of type olm
+*       Locations: [(0, 0, 0), ...]
+*
+*   0 connections in 0 projections
+*
+*   0 inputs in 0 input lists
+*
+*   1 explicit inputs (outside of input lists)
+*     Explicit Input of type pg_olm to pop0(cell 0), destination: unspecified
+*
+*******************************************************
+
+
+

We can check the connectivity graph of the model:

+
pynml -graph 10 olm_example_net.nml
+
+
+

which will give us this figure:

+
+Level 10 network graph generated by pynml +
+

Fig. 25 Level 10 network graph generated by pynml#

+
+
+
+
+
+

Simulating the model#

+

Please note that this example uses the NEURON simulator to simulate the model. +Please ensure that the NEURON_HOME environment variable is correctly set as noted here.

+

Now that we have declared and inspected our network model and all its components, we can proceed to simulate it. +We do this in the main function:

+
def main():
+    """Main function
+
+    Include the NeuroML model into a LEMS simulation file, run it, plot some
+    data.
+    """
+    # Simulation bits
+    sim_id = "olm_example_sim"
+    simulation = LEMSSimulation(sim_id=sim_id, duration=600, dt=0.01, simulation_seed=123)
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_olm_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_olm_cell_network")
+
+    # Recording information from the simulation
+    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+    simulation.add_column_to_output_file("output0", column_id="pop0_0_v", quantity="pop0[0]/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_soma_0",
+                                         quantity="pop0/0/olm/0/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_soma_0",
+                                         quantity="pop0/0/olm/1/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_axon_0",
+                                         quantity="pop0/0/olm/2/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_axon_0",
+                                         quantity="pop0/0/olm/3/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_0",
+                                         quantity="pop0/0/olm/4/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_0",
+                                         quantity="pop0/0/olm/6/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_1",
+                                         quantity="pop0/0/olm/5/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_1",
+                                         quantity="pop0/0/olm/7/v")
+    # Save LEMS simulation to file
+    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the NEURON simulator
+    pynml.run_lems_with_jneuroml_neuron(sim_file, max_memory="2G", nogui=True,
+                                        plot=False, skip_run=False)
+    # Plot the data
+    plot_data(sim_id)
+
+
+

Here we first create a LEMSSimulation instance and include our network NeuroML file in it. +We must inform LEMS what the target of the simulation is. +In our case, it’s the id of our network, single_olm_cell_network:

+
    simulation = LEMSSimulation(sim_id=sim_id, duration=600, dt=0.01, simulation_seed=123)
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_olm_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_olm_cell_network")
+
+
+

We also want to record some information, so we create an output file first with an id of output0:

+
    simulation.add_column_to_output_file("output0", column_id="pop0_0_v", quantity="pop0[0]/v")
+
+
+

Now, we can record any quantity that is exposed by NeuroML (any exposure). +Here, for example, we add columns for the membrane potentials v of the different segments of the cell.

+
    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_soma_0",
+                                         quantity="pop0/0/olm/0/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_soma_0",
+                                         quantity="pop0/0/olm/1/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_axon_0",
+                                         quantity="pop0/0/olm/2/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_axon_0",
+                                         quantity="pop0/0/olm/3/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_0",
+                                         quantity="pop0/0/olm/4/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_0",
+                                         quantity="pop0/0/olm/6/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_1",
+                                         quantity="pop0/0/olm/5/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_1",
+                                         quantity="pop0/0/olm/7/v")
+
+
+

The path required to point to the quantity (exposure) to be recorded needs to be correctly provided. +Here, where we use a population list that includes an instance of the cell, it is: population_id/instance_id/cell component type/segment id/exposure. (See tickets 15 and 16)

+

We then save the LEMS simulation file, and run our simulation with the NEURON simulator (since the default jNeuroML simulator can only simulate single compartment cells).

+
    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the NEURON simulator
+    pynml.run_lems_with_jneuroml_neuron(sim_file, max_memory="2G", nogui=True,
+                                        plot=False, skip_run=False)
+
+
+
+
+

Plotting the recorded variables#

+

To plot the variables that we recorded, we write a simple function that reads the data and uses the generate_plot utility function which generates the membrane potential graphs for different segments.

+
def plot_data(sim_id):
+    """Plot the sim data.
+
+    Load the data from the file and plot the graph for the membrane potential
+    using the pynml generate_plot utility function.
+
+    :sim_id: ID of simulaton
+
+    """
+    data_array = np.loadtxt(sim_id + ".dat")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 1]], "Membrane potential (soma seg 0)", show_plot_already=False, save_figure_to=sim_id + "_seg0_soma0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 2]], "Membrane potential (soma seg 1)", show_plot_already=False, save_figure_to=sim_id + "_seg1_soma0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 3]], "Membrane potential (axon seg 0)", show_plot_already=False, save_figure_to=sim_id + "_seg0_axon0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 4]], "Membrane potential (axon seg 1)", show_plot_already=False, save_figure_to=sim_id + "_seg1_axon0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+
+
+

This concludes this example. +Here we have seen how to create, simulate, record, and visualise a multi-compartment neuron. +In the next section, you will find an interactive notebook where you can play with this example.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NML2_examples/HH_single_compartment.html b/Userdocs/NML2_examples/HH_single_compartment.html new file mode 100644 index 00000000..36389121 --- /dev/null +++ b/Userdocs/NML2_examples/HH_single_compartment.html @@ -0,0 +1,1107 @@ + + + + + + + + + + + Interactive single compartment HH example — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Interactive single compartment HH example

+ +
+ +
+
+ + + + +
+ +
+

Interactive single compartment HH example#

+

To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see how to use this documentation. Please uncomment the line below if you use the Google Colab. (It does not include these packages by default).

+
+
+
#%pip install pyneuroml neuromllite NEURON
+
+
+
+
+
+
+
import math
+from neuroml import NeuroMLDocument
+from neuroml import Cell
+from neuroml import IonChannelHH
+from neuroml import GateHHRates
+from neuroml import BiophysicalProperties
+from neuroml import MembraneProperties
+from neuroml import ChannelDensity
+from neuroml import HHRate
+from neuroml import SpikeThresh
+from neuroml import SpecificCapacitance
+from neuroml import InitMembPotential
+from neuroml import IntracellularProperties
+from neuroml import IncludeType
+from neuroml import Resistivity
+from neuroml import Morphology, Segment, Point3DWithDiam
+from neuroml import Network, Population
+from neuroml import PulseGenerator, ExplicitInput
+import numpy as np
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+
+
+
+
+
+

Declare the model#

+
+

Create ion channels#

+
+
+
def create_na_channel():
+    """Create the Na channel.
+
+    This will create the Na channel and save it to a file.
+    It will also validate this file.
+
+    returns: name of the created file
+    """
+    na_channel = IonChannelHH(id="na_channel", notes="Sodium channel for HH cell", conductance="10pS", species="na")
+    gate_m = GateHHRates(id="m", instances="3", notes="m gate for na channel")
+
+    m_forward_rate = HHRate(type="HHExpLinearRate", rate="1per_ms", midpoint="-40mV", scale="10mV")
+    m_reverse_rate = HHRate(type="HHExpRate", rate="4per_ms", midpoint="-65mV", scale="-18mV")
+    gate_m.forward_rate = m_forward_rate
+    gate_m.reverse_rate = m_reverse_rate
+    na_channel.gate_hh_rates.append(gate_m)
+
+    gate_h = GateHHRates(id="h", instances="1", notes="h gate for na channel")
+    h_forward_rate = HHRate(type="HHExpRate", rate="0.07per_ms", midpoint="-65mV", scale="-20mV")
+    h_reverse_rate = HHRate(type="HHSigmoidRate", rate="1per_ms", midpoint="-35mV", scale="10mV")
+    gate_h.forward_rate = h_forward_rate
+    gate_h.reverse_rate = h_reverse_rate
+    na_channel.gate_hh_rates.append(gate_h)
+
+    na_channel_doc = NeuroMLDocument(id="na_channel", notes="Na channel for HH neuron")
+    na_channel_fn = "HH_example_na_channel.nml"
+    na_channel_doc.ion_channel_hhs.append(na_channel)
+
+    pynml.write_neuroml2_file(nml2_doc=na_channel_doc, nml2_file_name=na_channel_fn, validate=True)
+
+    return na_channel_fn
+
+
+
+
+
+
+
def create_k_channel():
+    """Create the K channel
+
+    This will create the K channel and save it to a file.
+    It will also validate this file.
+
+    :returns: name of the K channel file
+    """
+    k_channel = IonChannelHH(id="k_channel", notes="Potassium channel for HH cell", conductance="10pS", species="k")
+    gate_n = GateHHRates(id="n", instances="4", notes="n gate for k channel")
+    n_forward_rate = HHRate(type="HHExpLinearRate", rate="0.1per_ms", midpoint="-55mV", scale="10mV")
+    n_reverse_rate = HHRate(type="HHExpRate", rate="0.125per_ms", midpoint="-65mV", scale="-80mV")
+    gate_n.forward_rate = n_forward_rate
+    gate_n.reverse_rate = n_reverse_rate
+    k_channel.gate_hh_rates.append(gate_n)
+
+    k_channel_doc = NeuroMLDocument(id="k_channel", notes="k channel for HH neuron")
+    k_channel_fn = "HH_example_k_channel.nml"
+    k_channel_doc.ion_channel_hhs.append(k_channel)
+
+    pynml.write_neuroml2_file(nml2_doc=k_channel_doc, nml2_file_name=k_channel_fn, validate=True)
+
+    return k_channel_fn
+
+
+
+
+
+
+
def create_leak_channel():
+    """Create a leak channel
+
+    This will create the leak channel and save it to a file.
+    It will also validate this file.
+
+    :returns: name of leak channel nml file
+    """
+    leak_channel = IonChannelHH(id="leak_channel", conductance="10pS", notes="Leak conductance")
+    leak_channel_doc = NeuroMLDocument(id="leak_channel", notes="leak channel for HH neuron")
+    leak_channel_fn = "HH_example_leak_channel.nml"
+    leak_channel_doc.ion_channel_hhs.append(leak_channel)
+
+    pynml.write_neuroml2_file(nml2_doc=leak_channel_doc, nml2_file_name=leak_channel_fn, validate=True)
+
+    return leak_channel_fn
+
+
+
+
+
+
+

Create cell#

+
+
+
def create_cell():
+    """Create the cell.
+
+    :returns: name of the cell nml file
+    """
+    # Create the nml file and add the ion channels
+    hh_cell_doc = NeuroMLDocument(id="cell", notes="HH cell")
+    hh_cell_fn = "HH_example_cell.nml"
+    hh_cell_doc.includes.append(IncludeType(href=create_na_channel()))
+    hh_cell_doc.includes.append(IncludeType(href=create_k_channel()))
+    hh_cell_doc.includes.append(IncludeType(href=create_leak_channel()))
+
+    # Define a cell
+    hh_cell = Cell(id="hh_cell", notes="A single compartment HH cell")
+
+    # Define its biophysical properties
+    bio_prop = BiophysicalProperties(id="hh_b_prop")
+    #  notes="Biophysical properties for HH cell")
+
+    # Membrane properties are a type of biophysical properties
+    mem_prop = MembraneProperties()
+    # Add membrane properties to the biophysical properties
+    bio_prop.membrane_properties = mem_prop
+
+    # Append to cell
+    hh_cell.biophysical_properties = bio_prop
+
+    # Channel density for Na channel
+    na_channel_density = ChannelDensity(id="na_channels", cond_density="120.0 mS_per_cm2", erev="50.0 mV", ion="na", ion_channel="na_channel")
+    mem_prop.channel_densities.append(na_channel_density)
+
+    # Channel density for k channel
+    k_channel_density = ChannelDensity(id="k_channels", cond_density="360 S_per_m2", erev="-77mV", ion="k", ion_channel="k_channel")
+    mem_prop.channel_densities.append(k_channel_density)
+
+    # Leak channel
+    leak_channel_density = ChannelDensity(id="leak_channels", cond_density="3.0 S_per_m2", erev="-54.3mV", ion="non_specific", ion_channel="leak_channel")
+    mem_prop.channel_densities.append(leak_channel_density)
+
+    # Other membrane properties
+    mem_prop.spike_threshes.append(SpikeThresh(value="-20mV"))
+    mem_prop.specific_capacitances.append(SpecificCapacitance(value="1.0 uF_per_cm2"))
+    mem_prop.init_memb_potentials.append(InitMembPotential(value="-65mV"))
+
+    intra_prop = IntracellularProperties()
+    intra_prop.resistivities.append(Resistivity(value="0.03 kohm_cm"))
+
+    # Add to biological properties
+    bio_prop.intracellular_properties = intra_prop
+
+    # Morphology
+    morph = Morphology(id="hh_cell_morph")
+    #  notes="Simple morphology for the HH cell")
+    seg = Segment(id="0", name="soma", notes="Soma segment")
+    # We want a diameter such that area is 1000 micro meter^2
+    # surface area of a sphere is 4pi r^2 = 4pi diam^2
+    diam = math.sqrt(1000 / math.pi)
+    proximal = distal = Point3DWithDiam(x="0", y="0", z="0", diameter=str(diam))
+    seg.proximal = proximal
+    seg.distal = distal
+    morph.segments.append(seg)
+    hh_cell.morphology = morph
+
+    hh_cell_doc.cells.append(hh_cell)
+    pynml.write_neuroml2_file(nml2_doc=hh_cell_doc, nml2_file_name=hh_cell_fn, validate=True)
+    return hh_cell_fn
+
+
+
+
+
+
+

Create a network#

+
+
+
def create_network():
+    """Create the network
+
+    :returns: name of network nml file
+    """
+    net_doc = NeuroMLDocument(id="network",
+                              notes="HH cell network")
+    net_doc_fn = "HH_example_net.nml"
+    net_doc.includes.append(IncludeType(href=create_cell()))
+    # Create a population: convenient to create many cells of the same type
+    pop = Population(id="pop0", notes="A population for our cell", component="hh_cell", size=1)
+    # Input
+    pulsegen = PulseGenerator(id="pg", notes="Simple pulse generator", delay="100ms", duration="100ms", amplitude="0.08nA")
+
+    exp_input = ExplicitInput(target="pop0[0]", input="pg")
+
+    net = Network(id="single_hh_cell_network", note="A network with a single population")
+    net_doc.pulse_generators.append(pulsegen)
+    net.explicit_inputs.append(exp_input)
+    net.populations.append(pop)
+    net_doc.networks.append(net)
+
+    pynml.write_neuroml2_file(nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True)
+    return net_doc_fn
+
+
+
+
+
+
+
+

Plot the data we record#

+
+
+
def plot_data(sim_id):
+    """Plot the sim data.
+
+    Load the data from the file and plot the graph for the membrane potential
+    using the pynml generate_plot utility function.
+
+    :sim_id: ID of simulaton
+
+    """
+    data_array = np.loadtxt(sim_id + ".dat")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 1]], "Membrane potential", show_plot_already=False, save_figure_to=sim_id + "-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 2]], "channel current", show_plot_already=False, save_figure_to=sim_id + "-i.png", xaxis="time (s)", yaxis="channel current (A)")
+    pynml.generate_plot([data_array[:, 0], data_array[:, 0]], [data_array[:, 3], data_array[:, 4]], "current density", labels=["Na", "K"], show_plot_already=False, save_figure_to=sim_id + "-iden.png", xaxis="time (s)", yaxis="current density (A_per_m2)")
+
+
+
+
+
+
+

Create and run the simulation#

+

Create the simulation, run it, record data, and plot the recorded information.

+
+
+
def main():
+    """Main function
+
+    Include the NeuroML model into a LEMS simulation file, run it, plot some
+    data.
+    """
+    # Simulation bits
+    sim_id = "HH_single_compartment_example_sim"
+    simulation = LEMSSimulation(sim_id=sim_id, duration=300, dt=0.01, simulation_seed=123)
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_hh_cell_network")
+
+    # Recording information from the simulation
+    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+    simulation.add_column_to_output_file("output0", column_id="pop0[0]/v", quantity="pop0[0]/v")
+    simulation.add_column_to_output_file("output0", column_id="pop0[0]/iChannels", quantity="pop0[0]/iChannels")
+    simulation.add_column_to_output_file("output0", column_id="pop0[0]/na/iDensity", quantity="pop0[0]/hh_b_prop/membraneProperties/na_channels/iDensity/")
+    simulation.add_column_to_output_file("output0", column_id="pop0[0]/k/iDensity", quantity="pop0[0]/hh_b_prop/membraneProperties/k_channels/iDensity/")
+
+    # Save LEMS simulation to file
+    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the default jNeuroML simulator
+    pynml.run_lems_with_jneuroml(sim_file, max_memory="2G", nogui=True, plot=False)
+    # Plot the data
+    plot_data(sim_id)
+
+
+
+
+
+
+
if __name__ == "__main__":
+    main()
+
+
+
+
+
pyNeuroML >>> Written LEMS Simulation HH_single_compartment_example_sim to file: LEMS_HH_single_compartment_example_sim.xml
+pyNeuroML >>> Generating plot: Membrane potential
+
+
+
/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1688: MatplotlibDeprecationWarning: 
+The set_window_title function was deprecated in Matplotlib 3.4 and will be removed two minor releases later. Use manager.set_window_title or GUI-specific methods instead.
+  fig.canvas.set_window_title(title)
+/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
+  plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)
+/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1688: MatplotlibDeprecationWarning: 
+The set_window_title function was deprecated in Matplotlib 3.4 and will be removed two minor releases later. Use manager.set_window_title or GUI-specific methods instead.
+  fig.canvas.set_window_title(title)
+/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
+  plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)
+
+
+
pyNeuroML >>> Saved image to HH_single_compartment_example_sim-v.png of plot: Membrane potential
+pyNeuroML >>> Generating plot: channel current
+pyNeuroML >>> Saved image to HH_single_compartment_example_sim-i.png of plot: channel current
+pyNeuroML >>> Generating plot: current density
+pyNeuroML >>> Saved image to HH_single_compartment_example_sim-iden.png of plot: current density
+
+
+
/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1688: MatplotlibDeprecationWarning: 
+The set_window_title function was deprecated in Matplotlib 3.4 and will be removed two minor releases later. Use manager.set_window_title or GUI-specific methods instead.
+  fig.canvas.set_window_title(title)
+/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
+  plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)
+/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
+  plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)
+
+
+../../_images/fce843b119e9ef931e2fb37076f9f8b9a2f35cda36396498580c7374c2b8a456.png +../../_images/7d2474292dcb2b6a573030e67d9af7d7e579e2c3d8e56c1e32a56d343a0becb7.png +../../_images/523586e534cca4ab457b29b08c7b91242a2585c1d118638969d1474917a40993.png +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NML2_examples/IzhikevichNetwork.html b/Userdocs/NML2_examples/IzhikevichNetwork.html new file mode 100644 index 00000000..23e88cc5 --- /dev/null +++ b/Userdocs/NML2_examples/IzhikevichNetwork.html @@ -0,0 +1,1461 @@ + + + + + + + + + + + Interactive two population network example — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Interactive two population network example#

+

To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see how to use this documentation. Please uncomment the line below if you use the Google Colab. (It does not include these packages by default).

+
+
+
#%pip install pyneuroml neuromllite NEURON
+
+
+
+
+
+
+
#!/usr/bin/env python3
+"""
+Create a simple network with two populations.
+"""
+
+import random
+import numpy as np
+
+from neuroml.utils import component_factory
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+import neuroml.writers as writers
+
+
+
+
+
+

Declaring the NeuroML model#

+
+

Create a NeuroML document#

+
+
+
nml_doc = component_factory("NeuroMLDocument", id="IzNet")
+
+
+
+
+
+
+

Declare the Izhikevich cell and add it to the model document#

+
+
+
iz0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="iz2007RS0",
+    v0="-60mV",
+    C="100pF",
+    k="0.7nS_per_mV",
+    vr="-60mV",
+    vt="-40mV",
+    vpeak="35mV",
+    a="0.03per_ms",
+    b="-2nS",
+    c="-50.0mV",
+    d="100pA",
+)
+# Inspect the component, also show all members:
+iz0.info(True)
+
+
+
+
+
Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Izhikevich2007Cell are:
+* a (class: Nml2Quantity_pertime, Required)
+	* Contents ('ids'/<objects>): 0.03per_ms
+
+* C (class: Nml2Quantity_capacitance, Required)
+	* Contents ('ids'/<objects>): 100pF
+
+* annotation (class: Annotation, Optional)
+* b (class: Nml2Quantity_conductance, Required)
+	* Contents ('ids'/<objects>): -2nS
+
+* metaid (class: MetaId, Optional)
+* c (class: Nml2Quantity_voltage, Required)
+	* Contents ('ids'/<objects>): -50.0mV
+
+* d (class: Nml2Quantity_current, Required)
+	* Contents ('ids'/<objects>): 100pA
+
+* neuro_lex_id (class: NeuroLexId, Optional)
+* v0 (class: Nml2Quantity_voltage, Required)
+	* Contents ('ids'/<objects>): -60mV
+
+* properties (class: Property, Optional)
+* k (class: Nml2Quantity_conductancePerVoltage, Required)
+	* Contents ('ids'/<objects>): 0.7nS_per_mV
+
+* notes (class: xs:string, Optional)
+* vr (class: Nml2Quantity_voltage, Required)
+	* Contents ('ids'/<objects>): -60mV
+
+* vt (class: Nml2Quantity_voltage, Required)
+	* Contents ('ids'/<objects>): -40mV
+
+* vpeak (class: Nml2Quantity_voltage, Required)
+	* Contents ('ids'/<objects>): 35mV
+
+* id (class: NmlId, Required)
+	* Contents ('ids'/<objects>): iz2007RS0
+
+
+
"Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press\n\nPlease see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n\nValid members for Izhikevich2007Cell are:\n* a (class: Nml2Quantity_pertime, Required)\n\t* Contents ('ids'/<objects>): 0.03per_ms\n\n* C (class: Nml2Quantity_capacitance, Required)\n\t* Contents ('ids'/<objects>): 100pF\n\n* annotation (class: Annotation, Optional)\n* b (class: Nml2Quantity_conductance, Required)\n\t* Contents ('ids'/<objects>): -2nS\n\n* metaid (class: MetaId, Optional)\n* c (class: Nml2Quantity_voltage, Required)\n\t* Contents ('ids'/<objects>): -50.0mV\n\n* d (class: Nml2Quantity_current, Required)\n\t* Contents ('ids'/<objects>): 100pA\n\n* neuro_lex_id (class: NeuroLexId, Optional)\n* v0 (class: Nml2Quantity_voltage, Required)\n\t* Contents ('ids'/<objects>): -60mV\n\n* properties (class: Property, Optional)\n* k (class: Nml2Quantity_conductancePerVoltage, Required)\n\t* Contents ('ids'/<objects>): 0.7nS_per_mV\n\n* notes (class: xs:string, Optional)\n* vr (class: Nml2Quantity_voltage, Required)\n\t* Contents ('ids'/<objects>): -60mV\n\n* vt (class: Nml2Quantity_voltage, Required)\n\t* Contents ('ids'/<objects>): -40mV\n\n* vpeak (class: Nml2Quantity_voltage, Required)\n\t* Contents ('ids'/<objects>): 35mV\n\n* id (class: NmlId, Required)\n\t* Contents ('ids'/<objects>): iz2007RS0\n\n"
+
+
+
+
+
+
+

Declare the Synapse and add it to the model document#

+
+
+
syn0 = nml_doc.add(
+    "ExpOneSynapse", id="syn0", gbase="65nS", erev="0mV", tau_decay="3ms"
+)
+
+
+
+
+
+
+
nml_doc.info(True)
+
+
+
+
+
Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for NeuroMLDocument are:
+* compound_inputs (class: CompoundInput, Optional)
+* compound_input_dls (class: CompoundInputDL, Optional)
+* includes (class: IncludeType, Optional)
+* voltage_clamps (class: VoltageClamp, Optional)
+* extracellular_properties (class: ExtracellularProperties, Optional)
+* voltage_clamp_triples (class: VoltageClampTriple, Optional)
+* intracellular_properties (class: IntracellularProperties, Optional)
+* spike_arrays (class: SpikeArray, Optional)
+* morphology (class: Morphology, Optional)
+* timed_synaptic_inputs (class: TimedSynapticInput, Optional)
+* ion_channel (class: IonChannel, Optional)
+* spike_generators (class: SpikeGenerator, Optional)
+* ion_channel_hhs (class: IonChannelHH, Optional)
+* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)
+* ion_channel_v_shifts (class: IonChannelVShift, Optional)
+* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)
+* ion_channel_kses (class: IonChannelKS, Optional)
+* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)
+* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)
+* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)
+* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)
+* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)
+* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)
+* IF_curr_alpha (class: IF_curr_alpha, Optional)
+* alpha_synapses (class: AlphaSynapse, Optional)
+* IF_curr_exp (class: IF_curr_exp, Optional)
+* exp_one_synapses (class: ExpOneSynapse, Optional)
+	* Contents ('ids'/<objects>): ['syn0']
+
+* IF_cond_alpha (class: IF_cond_alpha, Optional)
+* exp_two_synapses (class: ExpTwoSynapse, Optional)
+* IF_cond_exp (class: IF_cond_exp, Optional)
+* exp_three_synapses (class: ExpThreeSynapse, Optional)
+* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)
+* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)
+* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)
+* double_synapses (class: DoubleSynapse, Optional)
+* HH_cond_exp (class: HH_cond_exp, Optional)
+* gap_junctions (class: GapJunction, Optional)
+* exp_cond_synapses (class: ExpCondSynapse, Optional)
+* silent_synapses (class: SilentSynapse, Optional)
+* alpha_cond_synapses (class: AlphaCondSynapse, Optional)
+* linear_graded_synapses (class: LinearGradedSynapse, Optional)
+* exp_curr_synapses (class: ExpCurrSynapse, Optional)
+* graded_synapses (class: GradedSynapse, Optional)
+* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)
+* annotation (class: Annotation, Optional)
+* biophysical_properties (class: BiophysicalProperties, Optional)
+* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)
+* cells (class: Cell, Optional)
+* networks (class: Network, Optional)
+* cell2_ca_poolses (class: Cell2CaPools, Optional)
+* ComponentType (class: ComponentType, Optional)
+* base_cells (class: BaseCell, Optional)
+* iaf_tau_cells (class: IafTauCell, Optional)
+* properties (class: Property, Optional)
+* iaf_tau_ref_cells (class: IafTauRefCell, Optional)
+* notes (class: xs:string, Optional)
+* iaf_cells (class: IafCell, Optional)
+* metaid (class: MetaId, Optional)
+* iaf_ref_cells (class: IafRefCell, Optional)
+* izhikevich_cells (class: IzhikevichCell, Optional)
+* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)
+	* Contents ('ids'/<objects>): ['iz2007RS0']
+
+* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)
+* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)
+* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)
+* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)
+* pulse_generators (class: PulseGenerator, Optional)
+* pulse_generator_dls (class: PulseGeneratorDL, Optional)
+* sine_generators (class: SineGenerator, Optional)
+* sine_generator_dls (class: SineGeneratorDL, Optional)
+* ramp_generators (class: RampGenerator, Optional)
+* ramp_generator_dls (class: RampGeneratorDL, Optional)
+* id (class: NmlId, Required)
+	* Contents ('ids'/<objects>): IzNet
+
+
+
"Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n\nValid members for NeuroMLDocument are:\n* compound_inputs (class: CompoundInput, Optional)\n* compound_input_dls (class: CompoundInputDL, Optional)\n* includes (class: IncludeType, Optional)\n* voltage_clamps (class: VoltageClamp, Optional)\n* extracellular_properties (class: ExtracellularProperties, Optional)\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n* intracellular_properties (class: IntracellularProperties, Optional)\n* spike_arrays (class: SpikeArray, Optional)\n* morphology (class: Morphology, Optional)\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n* ion_channel (class: IonChannel, Optional)\n* spike_generators (class: SpikeGenerator, Optional)\n* ion_channel_hhs (class: IonChannelHH, Optional)\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n* ion_channel_kses (class: IonChannelKS, Optional)\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\n* alpha_synapses (class: AlphaSynapse, Optional)\n* IF_curr_exp (class: IF_curr_exp, Optional)\n* exp_one_synapses (class: ExpOneSynapse, Optional)\n\t* Contents ('ids'/<objects>): ['syn0']\n\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\n* IF_cond_exp (class: IF_cond_exp, Optional)\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n* double_synapses (class: DoubleSynapse, Optional)\n* HH_cond_exp (class: HH_cond_exp, Optional)\n* gap_junctions (class: GapJunction, Optional)\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\n* silent_synapses (class: SilentSynapse, Optional)\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n* graded_synapses (class: GradedSynapse, Optional)\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n* annotation (class: Annotation, Optional)\n* biophysical_properties (class: BiophysicalProperties, Optional)\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n* cells (class: Cell, Optional)\n* networks (class: Network, Optional)\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\n* ComponentType (class: ComponentType, Optional)\n* base_cells (class: BaseCell, Optional)\n* iaf_tau_cells (class: IafTauCell, Optional)\n* properties (class: Property, Optional)\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n* notes (class: xs:string, Optional)\n* iaf_cells (class: IafCell, Optional)\n* metaid (class: MetaId, Optional)\n* iaf_ref_cells (class: IafRefCell, Optional)\n* izhikevich_cells (class: IzhikevichCell, Optional)\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n\t* Contents ('ids'/<objects>): ['iz2007RS0']\n\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n* pulse_generators (class: PulseGenerator, Optional)\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n* sine_generators (class: SineGenerator, Optional)\n* sine_generator_dls (class: SineGeneratorDL, Optional)\n* ramp_generators (class: RampGenerator, Optional)\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\n* id (class: NmlId, Required)\n\t* Contents ('ids'/<objects>): IzNet\n\n"
+
+
+
+
+
+
+
print(nml_doc.summary())
+
+
+
+
+
*******************************************************
+* NeuroMLDocument: IzNet
+*
+*  ExpOneSynapse: ['syn0']
+*  Izhikevich2007Cell: ['iz2007RS0']
+*
+*******************************************************
+
+
+
+
+
+
+

Declare a Network and add it to the model document#

+
+
+
net = nml_doc.add("Network", id="IzNet", validate=False)
+
+
+
+
+
+
+

Create two populations#

+
+
+
# create the first population
+size0 = 5
+pop0 = component_factory("Population", id="IzPop0", component=iz0.id, size=size0, type="population")
+# Set optional color property. Note: used later when generating plots
+pop0.add("Property", tag="color", value="0 0 .8")
+net.add(pop0)
+
+# create the second population
+size1 = 5
+pop1 = component_factory("Population", id="IzPop1", component=iz0.id, size=size1, type="population")
+pop1.add("Property", tag="color", value=".8 0 0")
+net.add(pop1)
+
+
+
+
+
<neuroml.nml.nml.Population at 0x7f53ace425c0>
+
+
+
+
+
+
+
net.validate()
+
+
+
+
+
+
+

Declare projections#

+
+
+
# create a projection from one population to another
+proj = net.add(
+    "Projection",
+    id="proj",
+    presynaptic_population=pop0.id,
+    postsynaptic_population=pop1.id,
+    synapse=syn0.id,
+)
+
+
+
+
+
+
+

Add the projections between populations and the external inputs#

+
+
+
random.seed(123)
+prob_connection = 0.8
+count = 0
+for pre in range(0, size0):
+    # pulse generator as explicit stimulus
+    pg = nml_doc.add(
+        "PulseGenerator",
+        id="pg_%i" % pre,
+        delay="0ms",
+        duration="10000ms",
+        amplitude="%f nA" % (0.1 + 0.1 * random.random()),
+    )
+
+    exp_input = net.add(
+        "ExplicitInput", target="%s[%i]" % (pop0.id, pre), input=pg.id
+    )
+
+    # synapses between populations
+    for post in range(0, size1):
+        if random.random() <= prob_connection:
+            syn = proj.add(
+                "Connection",
+                id=count,
+                pre_cell_id="../%s[%i]" % (pop0.id, pre),
+                post_cell_id="../%s[%i]" % (pop1.id, post),
+            )
+            count += 1
+
+
+
+
+
+
+
nml_doc.info(True)
+
+
+
+
+
Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for NeuroMLDocument are:
+* compound_inputs (class: CompoundInput, Optional)
+* compound_input_dls (class: CompoundInputDL, Optional)
+* includes (class: IncludeType, Optional)
+* voltage_clamps (class: VoltageClamp, Optional)
+* extracellular_properties (class: ExtracellularProperties, Optional)
+* voltage_clamp_triples (class: VoltageClampTriple, Optional)
+* intracellular_properties (class: IntracellularProperties, Optional)
+* spike_arrays (class: SpikeArray, Optional)
+* morphology (class: Morphology, Optional)
+* timed_synaptic_inputs (class: TimedSynapticInput, Optional)
+* ion_channel (class: IonChannel, Optional)
+* spike_generators (class: SpikeGenerator, Optional)
+* ion_channel_hhs (class: IonChannelHH, Optional)
+* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)
+* ion_channel_v_shifts (class: IonChannelVShift, Optional)
+* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)
+* ion_channel_kses (class: IonChannelKS, Optional)
+* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)
+* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)
+* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)
+* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)
+* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)
+* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)
+* IF_curr_alpha (class: IF_curr_alpha, Optional)
+* alpha_synapses (class: AlphaSynapse, Optional)
+* IF_curr_exp (class: IF_curr_exp, Optional)
+* exp_one_synapses (class: ExpOneSynapse, Optional)
+	* Contents ('ids'/<objects>): ['syn0']
+
+* IF_cond_alpha (class: IF_cond_alpha, Optional)
+* exp_two_synapses (class: ExpTwoSynapse, Optional)
+* IF_cond_exp (class: IF_cond_exp, Optional)
+* exp_three_synapses (class: ExpThreeSynapse, Optional)
+* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)
+* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)
+* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)
+* double_synapses (class: DoubleSynapse, Optional)
+* HH_cond_exp (class: HH_cond_exp, Optional)
+* gap_junctions (class: GapJunction, Optional)
+* exp_cond_synapses (class: ExpCondSynapse, Optional)
+* silent_synapses (class: SilentSynapse, Optional)
+* alpha_cond_synapses (class: AlphaCondSynapse, Optional)
+* linear_graded_synapses (class: LinearGradedSynapse, Optional)
+* exp_curr_synapses (class: ExpCurrSynapse, Optional)
+* graded_synapses (class: GradedSynapse, Optional)
+* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)
+* annotation (class: Annotation, Optional)
+* biophysical_properties (class: BiophysicalProperties, Optional)
+* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)
+* cells (class: Cell, Optional)
+* networks (class: Network, Optional)
+	* Contents ('ids'/<objects>): ['IzNet']
+
+* cell2_ca_poolses (class: Cell2CaPools, Optional)
+* ComponentType (class: ComponentType, Optional)
+* base_cells (class: BaseCell, Optional)
+* iaf_tau_cells (class: IafTauCell, Optional)
+* properties (class: Property, Optional)
+* iaf_tau_ref_cells (class: IafTauRefCell, Optional)
+* notes (class: xs:string, Optional)
+* iaf_cells (class: IafCell, Optional)
+* metaid (class: MetaId, Optional)
+* iaf_ref_cells (class: IafRefCell, Optional)
+* izhikevich_cells (class: IzhikevichCell, Optional)
+* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)
+	* Contents ('ids'/<objects>): ['iz2007RS0']
+
+* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)
+* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)
+* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)
+* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)
+* pulse_generators (class: PulseGenerator, Optional)
+	* Contents ('ids'/<objects>): ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']
+
+* pulse_generator_dls (class: PulseGeneratorDL, Optional)
+* sine_generators (class: SineGenerator, Optional)
+* sine_generator_dls (class: SineGeneratorDL, Optional)
+* ramp_generators (class: RampGenerator, Optional)
+* ramp_generator_dls (class: RampGeneratorDL, Optional)
+* id (class: NmlId, Required)
+	* Contents ('ids'/<objects>): IzNet
+
+
+
"Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n\nValid members for NeuroMLDocument are:\n* compound_inputs (class: CompoundInput, Optional)\n* compound_input_dls (class: CompoundInputDL, Optional)\n* includes (class: IncludeType, Optional)\n* voltage_clamps (class: VoltageClamp, Optional)\n* extracellular_properties (class: ExtracellularProperties, Optional)\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n* intracellular_properties (class: IntracellularProperties, Optional)\n* spike_arrays (class: SpikeArray, Optional)\n* morphology (class: Morphology, Optional)\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n* ion_channel (class: IonChannel, Optional)\n* spike_generators (class: SpikeGenerator, Optional)\n* ion_channel_hhs (class: IonChannelHH, Optional)\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n* ion_channel_kses (class: IonChannelKS, Optional)\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\n* alpha_synapses (class: AlphaSynapse, Optional)\n* IF_curr_exp (class: IF_curr_exp, Optional)\n* exp_one_synapses (class: ExpOneSynapse, Optional)\n\t* Contents ('ids'/<objects>): ['syn0']\n\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\n* IF_cond_exp (class: IF_cond_exp, Optional)\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n* double_synapses (class: DoubleSynapse, Optional)\n* HH_cond_exp (class: HH_cond_exp, Optional)\n* gap_junctions (class: GapJunction, Optional)\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\n* silent_synapses (class: SilentSynapse, Optional)\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n* graded_synapses (class: GradedSynapse, Optional)\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n* annotation (class: Annotation, Optional)\n* biophysical_properties (class: BiophysicalProperties, Optional)\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n* cells (class: Cell, Optional)\n* networks (class: Network, Optional)\n\t* Contents ('ids'/<objects>): ['IzNet']\n\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\n* ComponentType (class: ComponentType, Optional)\n* base_cells (class: BaseCell, Optional)\n* iaf_tau_cells (class: IafTauCell, Optional)\n* properties (class: Property, Optional)\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n* notes (class: xs:string, Optional)\n* iaf_cells (class: IafCell, Optional)\n* metaid (class: MetaId, Optional)\n* iaf_ref_cells (class: IafRefCell, Optional)\n* izhikevich_cells (class: IzhikevichCell, Optional)\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n\t* Contents ('ids'/<objects>): ['iz2007RS0']\n\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n* pulse_generators (class: PulseGenerator, Optional)\n\t* Contents ('ids'/<objects>): ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']\n\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n* sine_generators (class: SineGenerator, Optional)\n* sine_generator_dls (class: SineGeneratorDL, Optional)\n* ramp_generators (class: RampGenerator, Optional)\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\n* id (class: NmlId, Required)\n\t* Contents ('ids'/<objects>): IzNet\n\n"
+
+
+
+
+
+
+
print(nml_doc.summary())
+
+
+
+
+
*******************************************************
+* NeuroMLDocument: IzNet
+*
+*  ExpOneSynapse: ['syn0']
+*  Izhikevich2007Cell: ['iz2007RS0']
+*  PulseGenerator: ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']
+*
+*  Network: IzNet
+*
+*   10 cells in 2 populations 
+*     Population: IzPop0 with 5 components of type iz2007RS0
+*       Properties: color=0 0 .8; 
+*     Population: IzPop1 with 5 components of type iz2007RS0
+*       Properties: color=.8 0 0; 
+*
+*   20 connections in 1 projections 
+*     Projection: proj from IzPop0 to IzPop1, synapse: syn0
+*       20 connections: [(Connection 0: 0 -> 0), ...]
+*
+*   0 inputs in 0 input lists 
+*
+*   5 explicit inputs (outside of input lists)
+*     Explicit Input of type pg_0 to IzPop0(cell 0), destination: unspecified
+*     Explicit Input of type pg_1 to IzPop0(cell 1), destination: unspecified
+*     Explicit Input of type pg_2 to IzPop0(cell 2), destination: unspecified
+*     Explicit Input of type pg_3 to IzPop0(cell 3), destination: unspecified
+*     Explicit Input of type pg_4 to IzPop0(cell 4), destination: unspecified
+*
+*******************************************************
+
+
+
+
+
+
+

Write the NeuroML model to a NeuroML file and validate it#

+
+
+
nml_file = 'izhikevich2007_network.nml'
+writers.NeuroMLWriter.write(nml_doc, nml_file)
+
+print("Written network file to: " + nml_file)
+pynml.validate_neuroml2(nml_file)
+
+
+
+
+
pyNeuroML >>> INFO - Executing: (java -Xmx400M  -jar  "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar" -validate "izhikevich2007_network.nml" ) in directory: .
+
+
+
Written network file to: izhikevich2007_network.nml
+
+
+
pyNeuroML >>> INFO - Command completed. Output: 
+  jNeuroML >>   jNeuroML v0.12.0
+  jNeuroML >>  Validating: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/izhikevich2007_network.nml
+  jNeuroML >>  Valid against schema and all tests
+  jNeuroML >>  No warnings
+  jNeuroML >>  
+  jNeuroML >>  Validated 1 files: All valid and no warnings
+  jNeuroML >>  
+  jNeuroML >>  
+
+
+
True
+
+
+
+
+
+
+
+

Simulating the model#

+
+

Create a simulation instance of the model#

+
+
+
simulation_id = "example_izhikevich2007network_sim"
+simulation = LEMSSimulation(sim_id=simulation_id,
+                            duration=1000, dt=0.1, simulation_seed=123)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/izhikevich2007_network.nml
+
+
+
+
+
+
+

Define the output file to store spikes#

+
+
+
simulation.create_event_output_file(
+    "pop0", "%s.0.spikes.dat" % simulation_id, format='ID_TIME'
+)
+for pre in range(0, size0):
+    simulation.add_selection_to_event_output_file(
+        "pop0", pre, 'IzPop0[{}]'.format(pre), 'spike')
+
+simulation.create_event_output_file(
+    "pop1", "%s.1.spikes.dat" % simulation_id, format='ID_TIME'
+)
+for pre in range(0, size1):
+    simulation.add_selection_to_event_output_file(
+        "pop1", pre, 'IzPop1[{}]'.format(pre), 'spike')
+
+
+
+
+
+
+
+

Save the simulation to a file#

+
+
+
lems_simulation_file = simulation.save_to_file()
+
+
+
+
+
+
+

Run the simulation using jNeuroML#

+
+
+
pynml.run_lems_with_jneuroml_neuron(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+
+
+
+
pyNeuroML >>> INFO - Loading LEMS file: LEMS_example_izhikevich2007network_sim.xml and running with jNeuroML_NEURON
+pyNeuroML >>> INFO - Executing: (java -Xmx2G  -Djava.awt.headless=true -jar  "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar"  "LEMS_example_izhikevich2007network_sim.xml"  -neuron -run -compile -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed. Output: 
+  jNeuroML >>   jNeuroML v0.12.0
+  jNeuroML >>  (INFO) Reading from: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.xml
+  jNeuroML >>  (INFO) Creating NeuronWriter to output files to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples
+  jNeuroML >>  (INFO) Adding simulation Component(id=example_izhikevich2007network_sim type=Simulation) of network/component: IzNet (Type: network)
+  jNeuroML >>  (INFO) Adding population: IzPop0
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/iz2007RS0.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/iz2007RS0.mod exists and is identical
+  jNeuroML >>  (INFO) Adding population: IzPop1
+  jNeuroML >>  (INFO) -- Mod file for: iz2007RS0 has already been created
+  jNeuroML >>  (INFO) Adding projections/connections...
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/syn0.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/syn0.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_0.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_0.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_1.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_1.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_2.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_2.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_3.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_3.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_4.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_4.mod exists and is identical
+  jNeuroML >>  (INFO) Trying to compile mods in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples
+  jNeuroML >>  (INFO) Going to compile the mod files in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples, forcing recompile: false
+  jNeuroML >>  (INFO) Parent dir: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples
+  jNeuroML >>  (INFO) Assuming *nix environment...
+  jNeuroML >>  (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.la
+  jNeuroML >>  (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so
+  jNeuroML >>  (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so
+  jNeuroML >>  (INFO) commandToExecute: /usr/bin/nrnivmodl
+  jNeuroML >>  (INFO) Found previously compiled file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so
+  jNeuroML >>  (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so
+  jNeuroML >>  (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so
+  jNeuroML >>  (INFO) Not being asked to recompile, and no mod files exist in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples which are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so
+  jNeuroML >>  (INFO) Success in compiling mods: true
+  jNeuroML >>  (INFO) Have successfully executed command: python /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim_nrn.py
+  jNeuroML >>  (INFO) NRN Output >>> 
+  jNeuroML >>  (INFO) NRN Output >>>     Starting simulation in NEURON of 1000ms generated from NeuroML2 model...
+  jNeuroML >>  (INFO) NRN Output >>> 
+  jNeuroML >>  (INFO) NRN Output >>> Population IzPop0 contains 5 instance(s) of component: iz2007RS0 of type: izhikevich2007Cell
+  jNeuroML >>  (INFO) NRN Output >>> Population IzPop1 contains 5 instance(s) of component: iz2007RS0 of type: izhikevich2007Cell
+  jNeuroML >>  (INFO) NRN Output >>> Adding projection: proj, from IzPop0 to IzPop1 with synapse syn0, 20 connection(s)
+  jNeuroML >>  (INFO) NRN Output >>> Setting up the network to simulate took 0.000990 seconds
+  jNeuroML >>  (INFO) NRN Output >>> Running a simulation of 1000.0ms (dt = 0.1ms; seed=123)
+  jNeuroML >>  (INFO) NRN Output >>> Finished NEURON simulation in 0.022036 seconds (0.000367 mins)...
+  jNeuroML >>  (INFO) NRN Output >>> Saving results at t=999.9999999996382...
+  jNeuroML >>  (INFO) NRN Output >>> Saved data to: time.dat
+  jNeuroML >>  (INFO) NRN Output >>> Saved data to: example_izhikevich2007network_sim.1.spikes.dat
+  jNeuroML >>  (INFO) NRN Output >>> Saved data to: example_izhikevich2007network_sim.0.spikes.dat
+  jNeuroML >>  (INFO) NRN Output >>> Finished saving results in 0.002883 seconds
+  jNeuroML >>  (INFO) NRN Output >>> Done
+  jNeuroML >>  (INFO) Exit value for running NEURON: 0
+  jNeuroML >>  
+
+
+
True
+
+
+
+
+
+
+

Plot the recorded data#

+
+
+
# Load the data from the file and plot the spike times
+# using the pynml generate_plot utility function.
+data_array_0 = np.loadtxt("%s.0.spikes.dat" % simulation_id)
+data_array_1 = np.loadtxt("%s.1.spikes.dat" % simulation_id)
+times_0 = data_array_0[:,1]
+times_1 = data_array_1[:,1]
+ids_0 = data_array_0[:,0]
+ids_1 = [id+size0 for id in data_array_1[:,0]]
+pynml.generate_plot(
+    [times_0,times_1], [ids_0,ids_1],
+    "Spike times", show_plot_already=False,
+    save_figure_to="%s-spikes.png" % simulation_id,
+    xaxis="time (s)", yaxis="cell ID",
+    colors=['b','r'],
+    linewidths=['0','0'], markers=['.','.'],
+)
+
+
+
+
+
pyNeuroML >>> INFO - Generating plot: Spike times
+/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib64/python3.10/site-packages/pyneuroml/plot/Plot.py:174: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
+  plt.plot(
+pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/example_izhikevich2007network_sim-spikes.png of plot: Spike times
+pyNeuroML >>> INFO - Saved image to example_izhikevich2007network_sim-spikes.png of plot: Spike times
+
+
+
<AxesSubplot: xlabel='time (s)', ylabel='cell ID'>
+
+
+../../_images/35387de40bb3779c6e78fd8b3b87dcd64e3e7aafd3790055adfb904c42de8715.png +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NML2_examples/NeuroML-DB.html b/Userdocs/NML2_examples/NeuroML-DB.html new file mode 100644 index 00000000..8e3bacee --- /dev/null +++ b/Userdocs/NML2_examples/NeuroML-DB.html @@ -0,0 +1,1828 @@ + + + + + + + + + + + Create novel NeuroML models from components on NeuroML-DB — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Create novel NeuroML models from components on NeuroML-DB#

+

This notebook demonstrates how to access the NeuroML-DB database, extract elements in NeuroML format and use them to create new models

+
+
+
from pyneuroml import pynml
+import urllib.request, json 
+import requests
+import os
+
+
+
+
+
+

1) Search for, download and analyse channels accessed via the NeuroML-DB API#

+
+

1.1) Search in the database for a particular type of channel#

+
+
+
types = {'cell':'NMLCL','channel':'NMLCH'}
+
+# Helper method for search
+def search_neuromldb(search_term, type=None):
+    
+    with urllib.request.urlopen('https://neuroml-db.org/api/search?q=%s' % search_term.replace(' ','%20')) as url:
+        data = json.load(url)
+
+    for l in data:
+        if type!=None:
+            for type_ in types:
+                if type==type_ and not types[type_] in l['Model_ID']:
+                    data.remove(l)
+        if l in data:
+            print('%s: %s, %s %s %s'%(l['Model_ID'],l['Name'],l['First_Author'],l['Second_Author'],l['Publication_Year']))
+        
+    return data
+
+data = search_neuromldb("Fast Sodium", 'channel')
+
+
+
+
+
NMLCH000023: NaF Inactivating Fast Sodium, Maex De Schutter 1998
+NMLCH001490: NaTs Fast Inactivating Sodium, Gouwens Berg 2018
+NMLCH001398: NaTa Fast Inactivating Sodium, Hay Hill 2011
+NMLCH000171: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000170: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000169: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000168: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000167: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000166: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000165: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000164: NaP Persistent Noninactivating Sodium, Traub Buhl 2003
+NMLCH000163: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000162: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000161: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000160: NaF Fast Transient Inactivating Sodium, Traub Buhl 2003
+NMLCH000159: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000158: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005
+NMLCH000157: NaF Fast Transient Inactivating Sodium, Traub Buhl 2003
+NMLCH000131: NaF Fast Sodium, Pospischil Toledo-Rodriguez 2008
+NMLCH000111: NaTs Fast Inactivating Sodium, Colbert Pan 2002
+NMLCH000110: NaTa Fast Inactivating Sodium, Colbert Pan 2002
+NMLCH000008: NaF Inactivating Fast Sodium, Maex De Schutter 1998
+
+
+
+
+
+
+

1.2) Select one of these results and download it, and browse the contents#

+
+
+
# Helper method to retrieve a NeuroML file based on modelID
+def get_model_from_neuromldb(model_id, type):
+  
+    fname = '%s.%s.nml'%(model_id, type)
+
+    url = 'https://neuroml-db.org/render_xml_file?modelID=%s'%model_id
+    r = requests.get(url)
+    with open(fname , 'wb') as f:
+        f.write(r.content)
+
+    return pynml.read_neuroml2_file(fname), fname
+
+
+# Choose one of the channels
+chan_model_id = 'NMLCH001398'
+
+na_chan_doc, na_chan_fname_orig = get_model_from_neuromldb(chan_model_id, 'channel')
+
+na_chan = na_chan_doc.ion_channel[0] # select the first/only ion channel in the nml doc
+
+na_chan_fname = '%s.channel.nml'%na_chan.id
+os.rename(na_chan_fname_orig, na_chan_fname) # Rename for clarity
+
+print('Channel %s (in file %s) has notes: %s'%(na_chan.id, na_chan_fname, na_chan.notes))
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: NMLCH001398.channel.nml
+
+
+
Channel NaTa_t (in file NaTa_t.channel.nml) has notes: Fast inactivating Na+ current
+            
+Comment from original mod file: 
+:Reference :Colbert and Pan 2002
+
+
+
+
+
+
+

1.3) Plot the time course and steady state of this channel#

+
+
+
from pyneuroml.analysis.NML2ChannelAnalysis import run
+
+na_erev = 50 # mV
+run(channel_files=[na_chan_fname], ivCurve=True, erev=na_erev, clampDelay=5, clampDuration=10, duration=20)
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading LEMS file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_NaTa_t.xml and running with jNeuroML
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -Djava.awt.headless=true -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar"  /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_NaTa_t.xml  -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+
+
+../../_images/4a56a474313c1712b353a7a3f085449661b7fd7bd3ad4890b429cf4953c34026.png +../../_images/56d999547a37a2d351ead4521d2cd3a85d2739d8e00846d41c37a75edf9b698c.png +../../_images/b2aa4981e8cb6b519d72cd0d1e76aa6759e3e3913d827eeee9b12defecf38c63.png +../../_images/5532522cf7b99fb6f0dead129fa2c8e0c46d4a126add2a89309fec5a8405545b.png +../../_images/d3d84013cc4343a3e29f989e171b2aa9d3a91931c647b322d965986c06ad3967.png +
+
+
+
+

1.4) Find a Potassium channel#

+
+
+
data = search_neuromldb("Fast Potassium", 'channel')
+
+
+
+
+
NMLCH000113: K Fast Noninactivating Potassium, Rettig Wunder 1992
+NMLCH001627: KDr Fast Delayed Rectifier Potassium , Bezaire Raikov 2016
+NMLCH001611: KDr Fast Delayed Rectifier Potassium, Bezaire Raikov 2016
+NMLCH001609: KDr Fast Delayed Rectifier Potassium , Bezaire Raikov 2016
+NMLCH001549: K Fast Potassium, Boyle Cohen 2008
+NMLCH001529: KT Fast Inactivating Potassium, Gouwens Berg 2018
+NMLCH001465: K Fast Noninactivating Potassium, Gouwens Berg 2018
+NMLCH001400: KTst Fast Inactivating Potassium, Hay Hill 2011
+NMLCH001394: K Fast Noninactivating Potassium, Hay Hill 2011
+NMLCH000156: IM M Type Potassium, Traub Buhl 2003
+NMLCH000155: KDr Delayed Rectifier Potassium, Traub Buhl 2003
+NMLCH000154: KDr Delayed Rectifier Potassium Channel for Fast Spiking (FS) Interneurons, Traub Contreras 2005
+NMLCH000153: KCa BK Type Fast Calcium Dependent Potassium, Traub Buhl 2003
+NMLCH000152: KCa BK Type Fast Calcium Dependent Potassium, Traub Buhl 2003
+NMLCH000151: KCa AHP Type Calcium Dependent Potassium, Traub Buhl 2003
+NMLCH000149: KCa Slow AHP Type Calcium Dependent Potassium, Traub Buhl 2003
+NMLCH000148: IA A Type Potassium, Traub Buhl 2003
+NMLCH000146: K2 Type Slowly Activating and Inactivating Potassium, Traub Buhl 2003
+NMLCH000123: K Fast Potassium, Korngreen Sakmann 2000
+NMLCH000108: KTst Fast Inactivating Potassium, Korngreen Sakmann 2000
+
+
+
+
+
+
+
# Download one of these
+
+k_chan_doc, k_chan_fname_orig = get_model_from_neuromldb('NMLCH000113', 'channel')
+
+k_chan = k_chan_doc.ion_channel[0] # select the first ion channel in the nml doc
+
+k_chan_fname = '%s.channel.nml'%k_chan.id
+os.rename(k_chan_fname_orig, k_chan_fname) # Rename for clarity
+
+print('Channel %s (in file %s) has notes: %s'%(k_chan.id, k_chan_fname, k_chan.notes))
+
+k_erev = -77
+run(channel_files=[k_chan_fname], ivCurve=True, erev=k_erev)
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: NMLCH000113.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading LEMS file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_SKv3_1.xml and running with jNeuroML
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -Djava.awt.headless=true -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar"  /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_SKv3_1.xml  -nogui -I '') in directory: .
+
+
+
Channel SKv3_1 (in file SKv3_1.channel.nml) has notes: Fast, non inactivating K+ current
+            
+Comment from original mod file: 
+:Reference : :		Characterization of a Shaw-related potassium channel family in rat brain, The EMBO Journal, vol.11, no.7,2473-2486 (1992)
+
+
+
pyNeuroML >>> INFO - Command completed successfully!
+
+
+../../_images/39f32324242c88ea6fbae0ad8a168db12e69b5d4003d3aea56582b6a8dd6d1cd.png +../../_images/e7d9d45258035bf5b93bf809355fac7ebbf1889be2e005ea86bf616c5ae186cb.png +../../_images/b1d3fc1ed74d01cb82fe356e2a98ce3ecc57e951417ad2310ba7caa0587cc44c.png +../../_images/09b056ba3bcee90926ca2d8092d94e42615a0c2169f2d563a24732ed19aaf577.png +../../_images/fb5a80742e218f1e3932e62a5e81cb3c1b8b113c9dc0e6a3645ac2459f3c02d7.png +
+
+
+
+

1.5) Find a passive (leak) current#

+
+
+
data = search_neuromldb("Leak", 'channel')
+
+pas_chan_doc, pas_chan_fname = get_model_from_neuromldb(data[0]['Model_ID'], 'channel')
+pas_chan = pas_chan_doc.ion_channel[0] # select the first ion channel in the nml doc
+
+print('Channel %s has notes: %s'%(pas_chan.id, pas_chan.notes))
+
+
+
+
+
NMLCH000015: Passive Leak, Maex De Schutter 1998
+NMLCH001623: Passive Leak, Bezaire Raikov 2016
+NMLCH001601: Passive Leak, Smith Smith 2013
+NMLCH001590: Passive Leak, Prinz Bucher 2004
+NMLCH001545: Passive Leak, Boyle Cohen 2008
+NMLCH001471: Passive Leak, Gouwens Berg 2018
+NMLCH001427: Passive Leak, Hodgkin Huxley 1952
+NMLCH001403: Passive Leak, Hay Hill 2011
+NMLCH000172: Passive Leak, Traub Contreras 2005
+NMLCH000130: Passive Leak, Pospischil Toledo-Rodriguez 2008
+NMLCH000114: Passive Leak, Hodgkin Huxley 1952
+NMLCH000095: Passive Leak, Vervaeke Lorincz 2010
+NMLCH000027: Passive Leak, De Schutter Bower 1994
+NMLCH000024: Passive Leak, Maex De Schutter 1998
+NMLCH000016: Passive Leak, Maex De Schutter 1998
+NMLCH000007: Passive Leak, Migliore Ferrante 2005
+NMLCH000139: Passive Leak, Hodgkin Huxley 1952
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: NMLCH000015.channel.nml
+
+
+
Channel GranPassiveCond has notes: Simple leak conductance for Granule cell
+
+
+
+
+
+
+
+

2) Create a new cell model using these channels#

+
+

2.1) Create the Cell object, add channels and save to file#

+
+
+
from neuroml import *
+from neuroml.utils import component_factory
+import neuroml.writers as writers
+
+
+nml_doc = NeuroMLDocument(id="TestCell")
+
+cell = component_factory("Cell", id="novel_cell")
+nml_doc.add(cell)
+
+cell.add_segment(prox=[0,0,0,17.841242], 
+                 dist=[0,0,0,17.841242], 
+                 seg_type='soma')
+
+cell.set_resistivity('0.03 kohm_cm')
+cell.set_init_memb_potential('-65mV')
+cell.set_specific_capacitance('1.0 uF_per_cm2')
+cell.set_spike_thresh('0mV')
+
+
+cell.add_channel_density(nml_doc,
+                        cd_id='%s_chans'%na_chan.id,
+                        ion_channel=na_chan.id,
+                        cond_density='150 mS_per_cm2',
+                        ion_chan_def_file=na_chan_fname,
+                        erev="%s mV"%na_erev)
+
+cell.add_channel_density(nml_doc,
+                        cd_id='%s_chans'%k_chan.id,
+                        ion_channel=k_chan.id,
+                        cond_density='36 mS_per_cm2',
+                        ion_chan_def_file=k_chan_fname,
+                        erev="%s mV"%k_erev)
+
+cell.add_channel_density(nml_doc,
+                        cd_id='%s_chans'%pas_chan.id,
+                        ion_channel=pas_chan.id,
+                        cond_density='0.3 mS_per_cm2',
+                        ion_chan_def_file=pas_chan_fname,
+                        erev="-65 mV")
+
+
+
+cell_file = "%s.cell.nml"%nml_doc.id
+writers.NeuroMLWriter.write(nml_doc, cell_file)
+
+
+print("Written cell file to: " + cell_file)
+
+from neuroml.utils import validate_neuroml2
+
+validate_neuroml2(cell_file)
+
+#!cat TestCell.cell.nml
+
+
+pynml.summary(nml_doc, verbose=True)
+
+
+
+
+
Warning: Segment group all already exists.
+Warning: Segment group soma_group already exists.
+Written cell file to: TestCell.cell.nml
+It's valid!
+*******************************************************
+* NeuroMLDocument: TestCell
+*
+*
+*  Cell: novel_cell
+*    <Segment|0|Seg0>
+*      Parent segment: None (root segment)
+*      (0.0, 0.0, 0.0), diam 17.841242um -> (0.0, 0.0, 0.0), diam 17.841242um; seg length: 0.0 um
+*      Surface area: 1000.0000939925986 um2, volume: 2973.540612824116 um3
+*    Total length of 1 segment: 0.0 um; total area: 1000.0000939925986 um2
+*  
+*    SegmentGroup: soma_group,	1 member(s),	0 included group(s);	contains 1 segment, id: 0
+*    SegmentGroup: all,	1 member(s),	0 included group(s);	contains 1 segment, id: 0
+*  
+*    Channel density: NaTa_t_chans on all;	conductance of 150 mS_per_cm2 through ion chan NaTa_t with ion non_specific, erev: 50 mV
+*      Channel is on <Segment|0|Seg0>,	total conductance: 1500.0 S_per_m2 x 1.0000000939925986e-09 m2 = 1.500000140988898e-06 S (1500000.140988898 pS)
+*    Channel density: SKv3_1_chans on all;	conductance of 36 mS_per_cm2 through ion chan SKv3_1 with ion non_specific, erev: -77 mV
+*      Channel is on <Segment|0|Seg0>,	total conductance: 360.0 S_per_m2 x 1.0000000939925986e-09 m2 = 3.600000338373355e-07 S (360000.0338373355 pS)
+*    Channel density: GranPassiveCond_chans on all;	conductance of 0.3 mS_per_cm2 through ion chan GranPassiveCond with ion non_specific, erev: -65 mV
+*      Channel is on <Segment|0|Seg0>,	total conductance: 3.0 S_per_m2 x 1.0000000939925986e-09 m2 = 3.000000281977796e-09 S (3000.000281977796 pS)
+*  
+*    Specific capacitance on all: 1.0 uF_per_cm2
+*      Capacitance of <Segment|0|Seg0>,	total capacitance: 0.01 F_per_m2 x 1.0000000939925986e-09 m2 = 1.0000000939925987e-11 F (10.000000939925988 pF)
+*
+*******************************************************
+
+
+
/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: morphology has already been assigned.  Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.
+  warnings.warn(
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: biophysical_properties has already been assigned.  Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.
+  warnings.warn(
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: intracellular_properties has already been assigned.  Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.
+  warnings.warn(
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: membrane_properties has already been assigned.  Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.
+  warnings.warn(
+
+
+
+
+
+
+

2.2) Generate a plot of the actvity of the cell under current clamp input#

+
+
+
from pyneuroml.analysis import generate_current_vs_frequency_curve
+
+generate_current_vs_frequency_curve(cell_file,
+    cell.id,
+    start_amp_nA=-0.02,
+    end_amp_nA=0.06,
+    step_nA=0.01,
+    pre_zero_pulse=20,
+    post_zero_pulse=20,
+    analysis_duration=100,
+    temperature='34degC',
+    plot_voltage_traces=True)
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/TestCell.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NMLCH000015.channel.nml
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar" -validate iv_novel_cell.net.nml ) in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/iv_novel_cell.net.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/TestCell.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NMLCH000015.channel.nml
+pyNeuroML >>> INFO - Loading LEMS file: LEMS_iv_novel_cell.xml and running with jNeuroML
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -Djava.awt.headless=true -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar"  LEMS_iv_novel_cell.xml  -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/fromnumeric.py:3432: RuntimeWarning: Mean of empty slice.
+  return _methods._mean(a, axis=axis, dtype=dtype,
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/_methods.py:190: RuntimeWarning: invalid value encountered in double_scalars
+  ret = ret.dtype.type(ret / rcount)
+pyNeuroML >>> INFO - Generating plot: Membrane potential traces for: TestCell.cell.nml
+pyNeuroML >>> INFO - Generating plot: Firing frequency versus injected current for: TestCell.cell.nml
+
+
+../../_images/6fa63944a2646426dff6ade512d68a6ba6a53b9b7057c9bcd55eea8f8e1dba21.png +../../_images/d3f762fb7ec27fd7339831d1e89aa8dd8020512703457350a7edf9b4b328f4ff.png +
{-0.02: 0.0,
+ -0.01: 0.0,
+ 0.0: 0.0,
+ 0.01: 0.0,
+ 0.02: 0.0,
+ 0.03: 50.0,
+ 0.04: 70.0,
+ 0.05: 90.0}
+
+
+
+
+
+
+
+

3) Search for, download and analyse a complete NeuroML cell#

+
+

3.1) Search for and download the cell#

+
+
+
data = search_neuromldb("Burst Accommodating Martinotti", 'cell')
+
+
+
+
+
NMLCL000109: Layer 2/3 Burst Accommodating Martinotti Cell (3), Markram Muller 2015
+NMLCL000395: Layer 6 Burst Non-accommodating Martinotti Cell (4), Markram Muller 2015
+NMLCL000393: Layer 6 Burst Non-accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000345: Layer 4 Burst Non-accommodating Martinotti Cell (4), Markram Muller 2015
+NMLCL000343: Layer 4 Burst Non-accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000315: Layer 2/3 Burst Non-accommodating Martinotti Cell (4), Markram Muller 2015
+NMLCL000313: Layer 2/3 Burst Non-accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000191: Layer 6 Burst Accommodating Martinotti Cell (5), Markram Muller 2015
+NMLCL000190: Layer 6 Burst Accommodating Martinotti Cell (4), Markram Muller 2015
+NMLCL000188: Layer 6 Burst Accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000161: Layer 5 Burst Accommodating Martinotti Cell (5), Markram Muller 2015
+NMLCL000160: Layer 5 Burst Accommodating Martinotti Cell (4), Markram Muller 2015
+NMLCL000158: Layer 5 Burst Accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000157: Layer 5 Burst Accommodating Martinotti Cell (1), Markram Muller 2015
+NMLCL000136: Layer 4 Burst Accommodating Martinotti Cell (5), Markram Muller 2015
+NMLCL000134: Layer 4 Burst Accommodating Martinotti Cell (3), Markram Muller 2015
+NMLCL000133: Layer 4 Burst Accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000111: Layer 2/3 Burst Accommodating Martinotti Cell (5), Markram Muller 2015
+NMLCL000108: Layer 2/3 Burst Accommodating Martinotti Cell (2), Markram Muller 2015
+NMLCL000187: Layer 6 Burst Accommodating Martinotti Cell (1), Markram Muller 2015
+
+
+
+
+
+
+
model_id = 'NMLCL000109'
+
+def get_model_details_from_neuromldb(model_id):
+
+    url = 'https://neuroml-db.org/api/model?id=%s'%model_id
+    
+    with urllib.request.urlopen(url) as res:
+        model_details = json.load(res)
+        
+    for k in model_details['model']: print('%s:\t%s'%(k,model_details['model'][k]))
+        
+    return model_details
+    
+
+model_details = get_model_details_from_neuromldb(model_id)
+
+
+
+
+
Model_ID:	NMLCL000109
+Status:	CURRENT
+Errors:	None
+Status_Timestamp:	2018-12-24T16:29:21+00:00
+Type:	Cell
+Equations:	2061
+Runtime_Per_Step:	0.000510815108024267
+Max_Stable_DT:	0.0625
+Max_Stable_DT_Error:	0.969373115260111
+Max_Stable_DT_Benchmark_RunTime:	4.903825037032964
+Optimal_DT:	0.00781557069252977
+Optimal_DT_Error:	0.122802372280653
+Optimal_DT_Benchmark_RunTime:	39.21518682026722
+Optimal_DT_a:	0.000968992248062015
+Optimal_DT_b:	15.8634962901345
+Optimal_DT_c:	-0.0136485748710791
+CVODE_baseline_step_frequency:	13111.7719061286
+CVODE_steps_per_spike:	766.973690134512
+CVODE_Benchmark_RunTime:	10.615508666396945
+Name:	Layer 2/3 Burst Accommodating Martinotti Cell (3)
+Directory_Path:	/var/www/NeuroMLmodels/NMLCL000109
+File_Name:	bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+File_Updated:	None
+File_MD5_Checksum:	bcf74ccd8c6840f6c8f7551084c989b7
+File:	/var/www/NeuroMLmodels/NMLCL000109/bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+Publication_ID:	6000246
+Upload_Time:	2016-12-14T14:29:41+00:00
+Notes:	None
+ID_Helper:	175
+Sections:	40
+Compartments:	204
+Stability_Range_Low:	None
+Stability_Range_High:	None
+Is_Passive:	0
+Is_Intrinsically_Spiking:	0
+Resting_Voltage:	-71.2726975181673
+Rheobase_Low:	0.0469207763671875
+Rheobase_High:	0.048065185546875
+Threshold_Current_Low:	0.234375
+Threshold_Current_High:	0.29296875
+Bias_Voltage:	-80.0
+Bias_Current:	-0.0221022438906573
+CVODE_Active:	None
+Threshold:	None
+Is_GLIF:	0
+V_Variable:	None
+Steady_State_Delay:	None
+AP12AmplitudeDrop:	1.2698800006924
+AP1SSAmplitudeChange:	2.3903765783198
+AP1Amplitude:	72.1822400011024
+AP1WidthHalfHeight:	0.53
+AP1WidthPeakToTrough:	5.03000000000009
+AP1RateOfChangePeakToTrough:	-17.8182926253306
+AP1AHPDepth:	17.4437719043123
+AP2Amplitude:	70.91236000041
+AP2WidthHalfHeight:	0.55
+AP2WidthPeakToTrough:	6.22000000000003
+AP2RateOfChangePeakToTrough:	-14.2206642462703
+AP2AHPDepth:	17.5401716113915
+AP12AmplitudeChangePercent:	-1.75926931704115
+AP12HalfWidthChangePercent:	3.77358490566034
+AP12RateOfChangePeakToTroughPercentChange:	-20.1906459541805
+AP12AHPDepthPercentChange:	0.552631091532312
+InputResistance:	386.187465741356
+AP1DelayMean:	20.6200000000001
+AP1DelaySD:	0.0
+AP2DelayMean:	72.1300000000001
+AP2DelaySD:	0.0
+Burst1ISIMean:	60.255
+Burst1ISISD:	0.0
+InitialAccommodationMean:	-75.0
+SSAccommodationMean:	-50.0
+AccommodationRateToSS:	-0.143802128271498
+AccommodationAtSSMean:	-83.5991575049674
+AccommodationRateMeanAtSS:	166.006825685025
+ISICV:	2.95112315366106
+ISIMedian:	216.41
+ISIBurstMeanChange:	33.954571927781
+SpikeRateStrongStim:	10.0
+AP1DelayMeanStrongStim:	7.30999999999995
+AP1DelaySDStrongStim:	0.0
+AP2DelayMeanStrongStim:	33.8900000000001
+AP2DelaySDStrongStim:	0.0
+Burst1ISIMeanStrongStim:	28.135
+Burst1ISISDStrongStim:	0.0
+RampFirstSpike:	2046.34
+FrequencyFilterType:	Low-Pass
+FrequencyPassAbove:	29.0
+FrequencyPassBelow:	58.7316087498722
+Ephyz_Cluster_ID:	/3/1/4/
+Channel_Type:	None
+Time_Step:	None
+Max_Stable_DT_Benchmark_RunTime_HH:	911.1330720253954
+Optimal_DT_Benchmark_RunTime_HH:	466.46500114887556
+CVODE_Benchmark_RunTime_HH:	498.01998845545205
+Stability_Range_Low_Corr:	-1.875
+Stability_Range_High_Corr:	15.0
+
+
+
+
+
+
+
def get_full_model_from_neuromldb(model_id):
+    
+    fname = '%s.nml.zip'%(model_id)
+
+    url = 'https://neuroml-db.org/GetModelZip?modelID=%s&version=NeuroML'%model_id
+    r = requests.get(url)
+    with open(fname , 'wb') as f:
+        f.write(r.content)
+    
+
+    import zipfile
+    with zipfile.ZipFile(fname, 'r') as z:
+        z.extractall('.')
+
+    
+    print('Saved as %s'%fname)
+    
+get_full_model_from_neuromldb(model_id)
+
+detailed_cell_file = model_details['model']['File_Name']
+
+validate_neuroml2(detailed_cell_file)
+
+
+
+
+
Saved as NMLCL000109.nml.zip
+It's valid!
+
+
+
+
+
+
+

3.2) Generate 3D views of the cell#

+
+
+
from pyneuroml.plot.PlotMorphology import plot_2D
+
+planes = ['yz', 'xz', 'xy']
+for plane in planes:
+
+    plot_2D(detailed_cell_file,
+            plane2d  = plane,
+            min_width = 0,
+            verbose= False,
+            nogui = True,
+            square=False)
+
+detailed_cell_doc = pynml.read_neuroml2_file(detailed_cell_file)
+detailed_cell = detailed_cell_doc.cells[0]
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+
+
+../../_images/311f26e8521b553eb3294ccf6409e24912e380c92535323da32bd6aa0111080a.png +../../_images/10f7b384128918f1a4783bb32cf043728fd73a477f08fda6a6c09e9f49a0dd1d.png +../../_images/65f04ed77b9509a582a77992bacb723f0ebc056e88ab96c78af71d744f2150dd.png +
+
+
+
+

3.3) Analyse cell spiking behaviour#

+
+
+
martinotti_cell = detailed_cell_doc.cells[0]
+
+generate_current_vs_frequency_curve(detailed_cell_file,
+    martinotti_cell.id,
+    start_amp_nA=-0.02,
+    end_amp_nA=0.1,
+    step_nA=0.02,
+    pre_zero_pulse=100,
+    post_zero_pulse=100,
+    analysis_duration=1000,
+    plot_voltage_traces=True,
+    simulator='jNeuroML_NEURON')
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Tst.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Nap_Et2.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTs2_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ih.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/pas.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Im.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca_LVAst.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SK_E2.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Pst.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/CaDynamics_E2_NML2.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca.channel.nml
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar" -validate iv_bAC217_L23_MC_40be3bf0e8_0_0.net.nml ) in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/iv_bAC217_L23_MC_40be3bf0e8_0_0.net.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Tst.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Nap_Et2.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTs2_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ih.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/pas.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Im.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca_LVAst.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SK_E2.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Pst.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/CaDynamics_E2_NML2.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca.channel.nml
+pyNeuroML >>> INFO - Loading LEMS file: LEMS_iv_bAC217_L23_MC_40be3bf0e8_0_0.xml and running with jNeuroML_NEURON
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -Djava.awt.headless=true -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar"  LEMS_iv_bAC217_L23_MC_40be3bf0e8_0_0.xml  -neuron -run -compile -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/fromnumeric.py:3432: RuntimeWarning: Mean of empty slice.
+  return _methods._mean(a, axis=axis, dtype=dtype,
+/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/_methods.py:190: RuntimeWarning: invalid value encountered in double_scalars
+  ret = ret.dtype.type(ret / rcount)
+pyNeuroML >>> INFO - Generating plot: Membrane potential traces for: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+pyNeuroML >>> INFO - Generating plot: Firing frequency versus injected current for: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml
+
+
+../../_images/486734328bf2595816a031df84ce456e26a3f31c3bce9e2f25b38ae50d9bf955.png +../../_images/1921130adb0e4a2f5e4ebd1edccbfa8c217b6321b08f07a04036b3eca21588d9.png +
{-0.02: 0.0, 0.0: 0.0, 0.02: 0.0, 0.04: 0.0, 0.06: 5.0, 0.08: 8.0, 0.1: 10.0}
+
+
+
+
+
+
+
+

4) Create a small network using the cells#

+
+

4.1) Generate the NeuroML network#

+
+
+
from neuroml.utils import component_factory
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+import neuroml.writers as writers
+import random
+
+nml_doc = component_factory("NeuroMLDocument", id="NML_DB_Net")
+
+
+### Create the network
+net = nml_doc.add("Network", id="NML_DB_Net", validate=False)
+net.type="networkWithTemperature" 
+net.temperature="34.0degC"
+
+### Add a synapse
+syn0 = nml_doc.add(
+    "ExpOneSynapse", id="syn0", gbase="65nS", erev="0mV", tau_decay="3ms"
+)
+
+
+## Create the first population
+size_exc = 4
+nml_doc.add("IncludeType", href=cell_file)
+
+pop_exc = component_factory("Population", id="Exc", component=cell.id, size=size_exc, type="population")
+# Set optional color property. Note: used later when generating plots
+##pop0.add("Property", tag="color", value="0 0 .8")
+net.add(pop_exc)
+
+## Create the second population
+size_inh = 4
+nml_doc.add("IncludeType", href=detailed_cell_file)
+
+pop_inh = component_factory("Population", id="Inh", component=detailed_cell.id, size=size_inh, type="population")
+# Set optional color property. Note: used later when generating plots
+##pop1.add("Property", tag="color", value="0 0 .8")
+net.add(pop_inh)
+
+## Create connections and inputs
+random.seed(123)
+prob_connection = 0.8
+
+proj_count = 0
+
+projection = Projection(
+                    id="Proj_exc_inh",
+                    presynaptic_population=pop_exc.id,
+                    postsynaptic_population=pop_inh.id,
+                    synapse=syn0.id,
+                )
+
+net.projections.append(projection)
+
+for i in range(0, size_exc):
+    for j in range(0, size_inh):
+        if random.random() <= prob_connection: # probablistic connection...
+            connection = ConnectionWD(
+                id=proj_count,
+                pre_cell_id="%s[%i]" % (pop_exc.id, i),
+                post_cell_id="%s[%i]" % (pop_inh.id, j),
+                weight=random.random(),
+                delay='0ms'
+            )
+            projection.add(connection)
+            proj_count += 1
+
+for i in range(0, size_exc):
+    # pulse generator as explicit stimulus
+    pg = nml_doc.add(
+        "PulseGenerator",
+        id="pg_exc_%i" % i,
+        delay="20ms",
+        duration="260ms",
+        amplitude="%f nA" % (0.03 + 0.01 * random.random()),
+    )
+    
+    exp_input = net.add(
+        "ExplicitInput", target="%s[%i]" % (pop_exc.id, i), input=pg.id
+    )
+
+for i in range(0, size_inh):
+    # pulse generator as explicit stimulus
+    pg = nml_doc.add(
+        "PulseGenerator",
+        id="pg_inh_%i"%i,
+        delay="20ms",
+        duration="260ms",
+        amplitude="%f nA" % (0.02 + 0.02 * random.random()),
+    )
+    
+    exp_input = net.add(
+        "ExplicitInput", target="%s[%i]" % (pop_inh.id, i), input=pg.id
+    )
+
+
+print(nml_doc.summary())
+
+nml_net_file = 'NML_DB_network.net.nml'
+writers.NeuroMLWriter.write(nml_doc, nml_net_file)
+
+print("Written network file to: " + nml_net_file)
+pynml.validate_neuroml2(nml_net_file)
+
+
+
+
+
pyNeuroML >>> INFO - Executing: (java -Xmx400M  -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar" -validate NML_DB_network.net.nml ) in directory: .
+
+
+
*******************************************************
+* NeuroMLDocument: NML_DB_Net
+*
+*  ExpOneSynapse: ['syn0']
+*  IncludeType: ['TestCell.cell.nml', 'bAC217_L23_MC_40be3bf0e8_0_0.cell.nml']
+*  PulseGenerator: ['pg_exc_0', 'pg_exc_1', 'pg_exc_2', 'pg_exc_3', 'pg_inh_0', 'pg_inh_1', 'pg_inh_2', 'pg_inh_3']
+*
+*  Network: NML_DB_Net (temperature: 34.0degC)
+*
+*   8 cells in 2 populations 
+*     Population: Exc with 4 components of type novel_cell
+*     Population: Inh with 4 components of type bAC217_L23_MC_40be3bf0e8_0_0
+*
+*   13 connections in 1 projections 
+*     Projection: Proj_exc_inh from Exc to Inh, synapse: syn0
+*       13 connections (wd): [(Connection 0: 0 -> 0, weight: 0.087187, delay: 0.00000 ms), ...]
+*
+*   0 inputs in 0 input lists 
+*
+*   8 explicit inputs (outside of input lists)
+*     Explicit Input of type pg_exc_0 to Exc(cell 0), destination: unspecified
+*     Explicit Input of type pg_exc_1 to Exc(cell 1), destination: unspecified
+*     Explicit Input of type pg_exc_2 to Exc(cell 2), destination: unspecified
+*     Explicit Input of type pg_exc_3 to Exc(cell 3), destination: unspecified
+*     Explicit Input of type pg_inh_0 to Inh(cell 0), destination: unspecified
+*     Explicit Input of type pg_inh_1 to Inh(cell 1), destination: unspecified
+*     Explicit Input of type pg_inh_2 to Inh(cell 2), destination: unspecified
+*     Explicit Input of type pg_inh_3 to Inh(cell 3), destination: unspecified
+*
+*******************************************************
+Written network file to: NML_DB_network.net.nml
+
+
+
pyNeuroML >>> INFO - Command completed successfully!
+pyNeuroML >>> INFO - Output: 
+  jNeuroML >>   jNeuroML v0.13.0
+  jNeuroML >>  Validating: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NML_DB_network.net.nml
+  jNeuroML >>  Valid against schema and all tests
+  jNeuroML >>  No warnings
+  jNeuroML >>  
+  jNeuroML >>  Validated 1 files: All valid and no warnings
+  jNeuroML >>  
+  jNeuroML >>  
+
+
+
True
+
+
+
+
+
+
+

4.2) Generate views of the network#

+
+
+
from pyneuroml.pynml import generate_nmlgraph
+
+generate_nmlgraph(nml_net_file, level=-1, engine="dot")
+
+from IPython.display import Image
+Image(filename='%s.gv.png'%net.id,width=500)
+
+
+
+
+
pyNeuroML >>> INFO - Converting NML_DB_network.net.nml to graphical form, level -1, engine dot
+
+
+
neuromllite >>> Initiating GraphViz handler, level -1, engine: dot, seed: 1234
+Parsing: NML_DB_network.net.nml
+Loaded: NML_DB_network.net.nml as NeuroMLDocument
+neuromllite >>> Document: NML_DB_Net
+neuromllite >>> Network: NML_DB_Net
+neuromllite >>> Population: Exc, component: novel_cell (Cell), size: 4 cells, properties: {}
+neuromllite >>> Population: Inh, component: bAC217_L23_MC_40be3bf0e8_0_0 (Cell), size: 4 cells, properties: {}
+neuromllite >>> GRAPH PROJ: Proj_exc_inh (Exc (4) -> Inh (4), projection): w 1.0; wtot: 4.849021209484878; sign: 1; cond: 65.0 nS (65nS); all: {'projection': 58.85091239849243, 'inhibitory': -1e+100, 'excitatory': -1e+100, 'electricalProjection': -1e+100, 'continuousProjection': -1e+100} -> {'projection': 1.380338363104285, 'inhibitory': 1e+100, 'excitatory': 1e+100, 'electricalProjection': 1e+100, 'continuousProjection': 1e+100}
+neuromllite >>>  - conn Exc_0 -> Inh_0: 5.66713403897108 (5.66713403897108)
+neuromllite >>>  - conn Exc_0 -> Inh_1: 7.000515270998535 (7.000515270998535)
+neuromllite >>>  - conn Exc_0 -> Inh_3: 34.85313260220526 (34.85313260220526)
+neuromllite >>>  - conn Exc_1 -> Inh_0: 55.385630230408985 (55.385630230408985)
+neuromllite >>>  - conn Exc_1 -> Inh_1: 21.91908271210294 (21.91908271210294)
+neuromllite >>>  - conn Exc_1 -> Inh_2: 15.935617913644716 (15.935617913644716)
+neuromllite >>>  - conn Exc_1 -> Inh_3: 28.357926571989168 (28.357926571989168)
+neuromllite >>>  - conn Exc_2 -> Inh_0: 38.84396519171941 (38.84396519171941)
+neuromllite >>>  - conn Exc_2 -> Inh_1: 20.504833292831094 (20.504833292831094)
+neuromllite >>>  - conn Exc_2 -> Inh_2: 58.85091239849243 (58.85091239849243)
+neuromllite >>>  - conn Exc_2 -> Inh_3: 9.241379188047565 (9.241379188047565)
+neuromllite >>>  - conn Exc_3 -> Inh_0: 1.380338363104285 (1.380338363104285)
+neuromllite >>>  - conn Exc_3 -> Inh_2: 17.245910842001596 (17.245910842001596)
+neuromllite >>> Generating graph for: NML_DB_Net
+neuromllite >>> **************************************
+neuromllite >>> * Settings for GraphVizHandler: 
+neuromllite >>> *
+neuromllite >>> *    engine:                  dot
+neuromllite >>> *    level:                   -1
+neuromllite >>> *    is_cell_level:           True
+neuromllite >>> *    CUTOFF_INH_SYN_MV:       -50
+neuromllite >>> *    include_ext_inputs:      True
+neuromllite >>> *    include_input_pops:      True
+neuromllite >>> *    scale_by_post_pop_size:  True
+neuromllite >>> *    scale_by_post_pop_cond:  True
+neuromllite >>> *    min_weight_to_show:      0
+neuromllite >>> *    show_chem_conns:         True
+neuromllite >>> *    show_elect_conns:        True
+neuromllite >>> *    show_cont_conns:         True
+neuromllite >>> *    output_format:           png
+neuromllite >>> *
+neuromllite >>> * Used values: 
+neuromllite >>> *    syn_conds_used:          syn0:	 65.0 nS (65nS)
+neuromllite >>> *
+neuromllite >>> **************************************
+
+
+
/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/subprocess.py:1052: ResourceWarning: subprocess 25497 is still running
+  _warn("subprocess %s is still running" % self.pid,
+ResourceWarning: Enable tracemalloc to get the object allocation traceback
+pyNeuroML >>> INFO - Done with GraphViz...
+
+
+../../_images/cbcc1f3b0b4c7e625953206eac46859f31f199aa62d7a8ea9eb208ec67dda9c9.png +
+
+
+
+

4.3) Generate LEMS file to simulate the network#

+

See documentation about LEMS Simulation files.

+
+
+
simulation_id = "NML_DB_network_sim"
+simulation = LEMSSimulation(sim_id=simulation_id,
+                            duration=300, dt=0.025, simulation_seed=123)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_net_file, include_included=False)
+
+
+pops = [pop_exc, pop_inh]
+
+for pop in pops:
+    simulation.create_event_output_file(
+        f"{pop.id}_spikes", f"{pop.id}.spikes", format='ID_TIME'
+    )
+    simulation.create_output_file(pop.id, "%s.v.dat" % pop.id)
+
+    for pre in range(0, pop.size):
+        next_cell = '{}[{}]'.format(pop.id,pre)
+        simulation.add_selection_to_event_output_file(
+            f"{pop.id}_spikes", pop.component, next_cell, 'spike')
+
+        simulation.add_column_to_output_file(pop.id, f"v{pre}", f"{next_cell}/v")
+    
+    
+lems_simulation_file = simulation.save_to_file()
+
+print(f"Saved LEMS Simulation file to: {lems_simulation_file}")
+
+
+
+
+
Saved LEMS Simulation file to: LEMS_NML_DB_network_sim.xml
+
+
+
+
+
+
+

4.4) Run simulation of the network using NEURON#

+
+
+
traces = pynml.run_lems_with_jneuroml_neuron(
+    lems_simulation_file, max_memory="2G", nogui=True, load_saved_data=True, plot=True
+)
+
+
+
+
+
pyNeuroML >>> INFO - Loading LEMS file: LEMS_NML_DB_network_sim.xml and running with jNeuroML_NEURON
+pyNeuroML >>> INFO - Executing: (java -Xmx2G  -Djava.awt.headless=true -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar"  LEMS_NML_DB_network_sim.xml  -neuron -run -compile -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+pyNeuroML >>> WARNING - Reloading: Data loaded from ./Exc.v.dat (jNeuroML_NEURON)
+pyNeuroML >>> WARNING - Reloading: Data loaded from ./Inh.v.dat (jNeuroML_NEURON)
+
+
+../../_images/b2f5f0a7b7b908b19a44be5ea8289dfd0fe0d44b6e3017b6dbd63b20f3e06d2f.png +
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NML2_examples/OLM.html b/Userdocs/NML2_examples/OLM.html new file mode 100644 index 00000000..2ffc8bec --- /dev/null +++ b/Userdocs/NML2_examples/OLM.html @@ -0,0 +1,1284 @@ + + + + + + + + + + + Interactive multi-compartment OLM cell example — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Interactive multi-compartment OLM cell example

+ +
+ +
+
+ + + + +
+ +
+

Interactive multi-compartment OLM cell example#

+

To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see how to use this documentation. Please uncomment the line below if you use the Google Colab. (It does not include these packages by default).

+
+
+
#%pip install pyneuroml neuromllite NEURON
+
+
+
+
+
+
+
#!/usr/bin/env python3
+"""
+Multi-compartmental OLM cell example
+
+File: olm-example.py
+
+Copyright 2023 NeuroML contributors
+Authors: Padraig Gleeson, Ankur Sinha
+"""
+
+import neuroml
+from neuroml import NeuroMLDocument
+from neuroml.utils import component_factory
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+from pyneuroml.plot.PlotMorphology import plot_2D
+import numpy as np
+
+
+
+
+

The CellBuilder module file can be found in the same folder as the Python script. It is used to define the helper functions that we use in our main file.

+
+

Declaring the NeuroML model#

+
+

Create the cell#

+

In this example, we do not create the ion channels. We include ion channels that are already provided in NeuroML files.

+
+
+
def create_olm_cell():
+    """Create the complete cell.
+
+    :returns: cell object
+    """
+    nml_cell_doc = component_factory("NeuroMLDocument", id="oml_cell")
+    cell = nml_cell_doc.add("Cell", id="olm", neuro_lex_id="NLXCELL:091206")  # type neuroml.Cell
+    nml_cell_file = cell.id + ".cell.nml"
+
+    cell.summary()
+    cell.info(show_contents=True)
+    cell.morphology.info(show_contents=True)
+
+    # Add two soma segments to an unbranched segment group
+    cell.add_unbranched_segment_group("soma_0")
+    diam = 10.0
+    soma_0 = cell.add_segment(
+        prox=[0.0, 0.0, 0.0, diam],
+        dist=[0.0, 10., 0.0, diam],
+        name="Seg0_soma_0",
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    soma_1 = cell.add_segment(
+        prox=None,
+        dist=[0.0, 10. + 10., 0.0, diam],
+        name="Seg1_soma_0",
+        parent=soma_0,
+        group_id="soma_0",
+        seg_type="soma"
+    )
+
+    # Add axon segments
+    diam = 1.5
+    cell.add_unbranched_segments(
+        [
+            [0.0, 0.0, 0.0, diam],
+            [0.0, -75, 0.0, diam],
+            [0.0, -150, 0.0, diam],
+        ],
+        parent=soma_0,
+        fraction_along=0.0,
+        group_id="axon_0",
+        seg_type="axon"
+    )
+
+    # Add 2 dendrite segments, using the branching utility function
+
+    diam = 3.0
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [100, 120, 0.0, diam],
+            [177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_0",
+        seg_type="dendrite"
+    )
+
+    cell.add_unbranched_segments(
+        [
+            [0.0, 20.0, 0.0, diam],
+            [-100, 120, 0.0, diam],
+            [-177, 197, 0.0, diam],
+        ],
+        parent=soma_1,
+        fraction_along=1.0,
+        group_id="dend_1",
+        seg_type="dendrite"
+    )
+
+    # color groups for morphology plots
+    den_seg_group = cell.get_segment_group("dendrite_group")
+    den_seg_group.add("Property", tag="color", value="0.8 0 0")
+
+    ax_seg_group = cell.get_segment_group("axon_group")
+    ax_seg_group.add("Property", tag="color", value="0 0.8 0")
+
+    soma_seg_group = cell.get_segment_group("soma_group")
+    soma_seg_group.add("Property", tag="color", value="0 0 0.8")
+
+    # Other cell properties
+    cell.set_init_memb_potential("-67mV")
+    cell.set_resistivity("0.15 kohm_cm")
+    cell.set_specific_capacitance("1.3 uF_per_cm2")
+
+    # channels
+    # leak
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="leak_all",
+                             cond_density="0.01 mS_per_cm2",
+                             ion_channel="leak_chan",
+                             ion_chan_def_file="olm-example/leak_chan.channel.nml",
+                             erev="-67mV",
+                             ion="non_specific")
+    # HCNolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="HCNolm_soma",
+                             cond_density="0.5 mS_per_cm2",
+                             ion_channel="HCNolm",
+                             ion_chan_def_file="olm-example/HCNolm.channel.nml",
+                             erev="-32.9mV",
+                             ion="h",
+                             group_id="soma_group")
+    # Kdrfast_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_soma",
+                             cond_density="73.37 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # Kdrfast_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_dendrite",
+                             cond_density="105.8 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Kdrfast_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Kdrfast_axon",
+                             cond_density="117.392 mS_per_cm2",
+                             ion_channel="Kdrfast",
+                             ion_chan_def_file="olm-example/Kdrfast.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="axon_group")
+    # KvAolm_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_soma",
+                             cond_density="4.95 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="soma_group")
+    # KvAolm_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="KvAolm_dendrite",
+                             cond_density="2.8 mS_per_cm2",
+                             ion_channel="KvAolm",
+                             ion_chan_def_file="olm-example/KvAolm.channel.nml",
+                             erev="-77mV",
+                             ion="k",
+                             group_id="dendrite_group")
+    # Nav_soma
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_soma",
+                             cond_density="10.7 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="soma_group")
+    # Nav_dendrite
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_dendrite",
+                             cond_density="23.4 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="dendrite_group")
+    # Nav_axon
+    cell.add_channel_density(nml_cell_doc,
+                             cd_id="Nav_axon",
+                             cond_density="17.12 mS_per_cm2",
+                             ion_channel="Nav",
+                             ion_chan_def_file="olm-example/Nav.channel.nml",
+                             erev="50mV",
+                             ion="na",
+                             group_id="axon_group")
+
+    cell.optimise_segment_groups()
+    cell.validate(recursive=True)
+    pynml.write_neuroml2_file(nml_cell_doc, nml_cell_file, True, True)
+    plot_2D(nml_cell_file, plane2d="xy", nogui=True,
+            save_to_file="olm.cell.xy.png")
+    return nml_cell_file
+
+
+
+
+
+
+

Create the network#

+
+
+
def create_olm_network():
+    """Create the network
+
+    :returns: name of network nml file
+    """
+    net_doc = NeuroMLDocument(id="network",
+                              notes="OLM cell network")
+    net_doc_fn = "olm_example_net.nml"
+    net_doc.add("IncludeType", href=create_olm_cell())
+    net = net_doc.add("Network", id="single_olm_cell_network", validate=False)
+    # Create a population: convenient to create many cells of the same type
+    pop = net.add("Population", id="pop0", notes="A population for our cell",
+                  component="olm", size=1, type="populationList",
+                  validate=False)
+    pop.add("Instance", id=0, location=component_factory("Location", x=0., y=0., z=0.))
+    # Input
+    net_doc.add("PulseGenerator", id="pg_olm", notes="Simple pulse generator", delay="100ms", duration="100ms", amplitude="0.08nA")
+
+    net.add("ExplicitInput", target="pop0[0]", input="pg_olm")
+
+    pynml.write_neuroml2_file(nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True)
+    return net_doc_fn
+
+
+
+
+
+
+
+

Plot the data we record#

+
+
+
def plot_data(sim_id):
+    """Plot the sim data.
+
+    Load the data from the file and plot the graph for the membrane potential
+    using the pynml generate_plot utility function.
+
+    :sim_id: ID of simulaton
+
+    """
+    data_array = np.loadtxt(sim_id + ".dat")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 1]], "Membrane potential (soma seg 0)", show_plot_already=False, save_figure_to=sim_id + "_seg0_soma0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 2]], "Membrane potential (soma seg 1)", show_plot_already=False, save_figure_to=sim_id + "_seg1_soma0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 3]], "Membrane potential (axon seg 0)", show_plot_already=False, save_figure_to=sim_id + "_seg0_axon0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+    pynml.generate_plot([data_array[:, 0]], [data_array[:, 4]], "Membrane potential (axon seg 1)", show_plot_already=False, save_figure_to=sim_id + "_seg1_axon0-v.png", xaxis="time (s)", yaxis="membrane potential (V)")
+
+
+
+
+
+
+

Create and run the simulaton#

+
+
+
def main():
+    """Main function
+
+    Include the NeuroML model into a LEMS simulation file, run it, plot some
+    data.
+    """
+    # Simulation bits
+    sim_id = "olm_example_sim"
+    simulation = LEMSSimulation(sim_id=sim_id, duration=600, dt=0.01, simulation_seed=123)
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_olm_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_olm_cell_network")
+
+    # Recording information from the simulation
+    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+    simulation.add_column_to_output_file("output0", column_id="pop0_0_v", quantity="pop0[0]/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_soma_0",
+                                         quantity="pop0/0/olm/0/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_soma_0",
+                                         quantity="pop0/0/olm/1/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_axon_0",
+                                         quantity="pop0/0/olm/2/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_axon_0",
+                                         quantity="pop0/0/olm/3/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_0",
+                                         quantity="pop0/0/olm/4/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_0",
+                                         quantity="pop0/0/olm/6/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg0_dend_1",
+                                         quantity="pop0/0/olm/5/v")
+    simulation.add_column_to_output_file("output0",
+                                         column_id="pop0_0_v_Seg1_dend_1",
+                                         quantity="pop0/0/olm/7/v")
+    # Save LEMS simulation to file
+    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the NEURON simulator
+    pynml.run_lems_with_jneuroml_neuron(sim_file, max_memory="2G", nogui=True,
+                                        plot=False, skip_run=False)
+    # Plot the data
+    plot_data(sim_id)
+
+
+
+
+
+
+
if __name__ == "__main__":
+    main()
+
+
+
+
+
pyNeuroML >>> INFO - Executing: (java -Xmx400M  -jar  "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar" -validate "olm.cell.nml" ) in directory: .
+
+
+
*******************************************************
+* Cell: olm
+* Notes: None
+* Segments: 0
+* SegmentGroups: 4
+*******************************************************
+Cell -- Cell with  **segment** s specified in a  **morphology**  element along with details on its  **biophysicalProperties** . NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v**  of this cell represents the membrane potential in that isopotential segment.
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Cell are:
+* morphology_attr (class: NmlId, Optional)
+* biophysical_properties_attr (class: NmlId, Optional)
+* morphology (class: Morphology, Optional)
+	* Contents ('ids'/<objects>): 'morphology'
+
+* neuro_lex_id (class: NeuroLexId, Optional)
+	* Contents ('ids'/<objects>): NLXCELL:091206
+
+* biophysical_properties (class: BiophysicalProperties, Optional)
+	* Contents ('ids'/<objects>): 'biophys'
+
+* annotation (class: Annotation, Optional)
+* properties (class: Property, Optional)
+* notes (class: xs:string, Optional)
+* id (class: NmlId, Required)
+	* Contents ('ids'/<objects>): olm
+
+* metaid (class: MetaId, Optional)
+
+Morphology -- The collection of  **segment** s which specify the 3D structure of the cell, along with a number of  **segmentGroup** s
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Morphology are:
+* segments (class: Segment, Required)
+* segment_groups (class: SegmentGroup, Optional)
+	* Contents ('ids'/<objects>): ['all', 'soma_group', 'axon_group', 'dendrite_group']
+
+* annotation (class: Annotation, Optional)
+* properties (class: Property, Optional)
+* notes (class: xs:string, Optional)
+* id (class: NmlId, Required)
+	* Contents ('ids'/<objects>): morphology
+
+* metaid (class: MetaId, Optional)
+
+
+
pyNeuroML >>> INFO - Command completed. Output: 
+  jNeuroML >>   jNeuroML v0.12.0
+  jNeuroML >>  Validating: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.cell.nml
+  jNeuroML >>  Valid against schema and all tests
+  jNeuroML >>  No warnings
+  jNeuroML >>  
+  jNeuroML >>  Validated 1 files: All valid and no warnings
+  jNeuroML >>  
+  jNeuroML >>  
+pyNeuroML >>> INFO - Loading NeuroML2 file: olm.cell.nml
+pyNeuroML >>> INFO - Including included files (included already: [])
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml
+pyNeuroML >>> INFO - Including included files (included already: [])
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml
+pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml'])
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml
+pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml'])
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/KvAolm.channel.nml
+pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml'])
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Nav.channel.nml
+pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/KvAolm.channel.nml'])
+pyNeuroML >>> INFO - Executing: (java -Xmx400M  -jar  "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar" -validate "olm_example_net.nml" ) in directory: .
+
+
+
Saved image on plane xy to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.cell.xy.png of plot: 2D plot of olm from olm.cell.nml
+
+
+
pyNeuroML >>> INFO - Command completed. Output: 
+  jNeuroML >>   jNeuroML v0.12.0
+  jNeuroML >>  Validating: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_net.nml
+  jNeuroML >>  Valid against schema and all tests
+  jNeuroML >>  No warnings
+  jNeuroML >>  
+  jNeuroML >>  Validated 1 files: All valid and no warnings
+  jNeuroML >>  
+  jNeuroML >>  
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_net.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.cell.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/KvAolm.channel.nml
+pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Nav.channel.nml
+pyNeuroML >>> INFO - Loading LEMS file: LEMS_olm_example_sim.xml and running with jNeuroML_NEURON
+pyNeuroML >>> INFO - Executing: (java -Xmx2G  -Djava.awt.headless=true -jar  "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar"  "LEMS_olm_example_sim.xml"  -neuron -run -compile -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed. Output: 
+  jNeuroML >>   jNeuroML v0.12.0
+  jNeuroML >>  (INFO) Reading from: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_olm_example_sim.xml
+  jNeuroML >>  (INFO) Creating NeuronWriter to output files to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples
+  jNeuroML >>  (INFO) Adding simulation Component(id=olm_example_sim type=Simulation) of network/component: single_olm_cell_network (Type: network)
+  jNeuroML >>  (INFO) Adding population: pop0
+  jNeuroML >>  (INFO) -- Writing to hoc: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.hoc
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/leak_chan.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/leak_chan.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/HCNolm.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/HCNolm.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Kdrfast.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Kdrfast.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/KvAolm.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/KvAolm.mod exists and is identical
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Nav.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Nav.mod exists and is identical
+  jNeuroML >>  (INFO) Adding projections/connections...
+  jNeuroML >>  (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_olm.mod
+  jNeuroML >>  (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_olm.mod exists and is identical
+  jNeuroML >>  (INFO) Trying to compile mods in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples
+  jNeuroML >>  (INFO) Going to compile the mod files in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples, forcing recompile: false
+  jNeuroML >>  (INFO) Parent dir: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples
+  jNeuroML >>  (INFO) Assuming *nix environment...
+  jNeuroML >>  (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.la
+  jNeuroML >>  (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so
+  jNeuroML >>  (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so
+  jNeuroML >>  (INFO) commandToExecute: /usr/bin/nrnivmodl
+  jNeuroML >>  (INFO) Found previously compiled file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so
+  jNeuroML >>  (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so
+  jNeuroML >>  (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so
+  jNeuroML >>  (INFO) Not being asked to recompile, and no mod files exist in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples which are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so
+  jNeuroML >>  (INFO) Success in compiling mods: true
+  jNeuroML >>  (INFO) Have successfully executed command: python /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_olm_example_sim_nrn.py
+  jNeuroML >>  (INFO) NRN Output >>> 
+  jNeuroML >>  (INFO) NRN Output >>>     Starting simulation in NEURON of 600ms generated from NeuroML2 model...
+  jNeuroML >>  (INFO) NRN Output >>> 
+  jNeuroML >>  (INFO) NRN Output >>> Population pop0 contains 1 instance(s) of component: olm of type: cell
+  jNeuroML >>  (INFO) NRN Output >>> 	1 
+  jNeuroML >>  (INFO) NRN Output >>> Setting up the network to simulate took 0.006119 seconds
+  jNeuroML >>  (INFO) NRN Output >>> Running a simulation of 600.0ms (dt = 0.01ms; seed=123)
+  jNeuroML >>  (INFO) NRN Output >>> Finished NEURON simulation in 0.424608 seconds (0.007077 mins)...
+  jNeuroML >>  (INFO) NRN Output >>> Saving results at t=599.9999999995268...
+  jNeuroML >>  (INFO) NRN Output >>> Saved data to: time.dat
+  jNeuroML >>  (INFO) NRN Output >>> Saved data to: olm_example_sim.dat
+  jNeuroML >>  (INFO) NRN Output >>> Finished saving results in 0.455872 seconds
+  jNeuroML >>  (INFO) NRN Output >>> Done
+  jNeuroML >>  (INFO) Exit value for running NEURON: 0
+  jNeuroML >>  
+pyNeuroML >>> INFO - Generating plot: Membrane potential (soma seg 0)
+/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib64/python3.10/site-packages/pyneuroml/plot/Plot.py:186: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
+  plt.plot(
+pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg0_soma0-v.png of plot: Membrane potential (soma seg 0)
+
+
+
pyNeuroML >>> INFO - Saved image to olm_example_sim_seg0_soma0-v.png of plot: Membrane potential (soma seg 0)
+pyNeuroML >>> INFO - Generating plot: Membrane potential (soma seg 1)
+pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg1_soma0-v.png of plot: Membrane potential (soma seg 1)
+pyNeuroML >>> INFO - Saved image to olm_example_sim_seg1_soma0-v.png of plot: Membrane potential (soma seg 1)
+pyNeuroML >>> INFO - Generating plot: Membrane potential (axon seg 0)
+pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg0_axon0-v.png of plot: Membrane potential (axon seg 0)
+pyNeuroML >>> INFO - Saved image to olm_example_sim_seg0_axon0-v.png of plot: Membrane potential (axon seg 0)
+pyNeuroML >>> INFO - Generating plot: Membrane potential (axon seg 1)
+pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg1_axon0-v.png of plot: Membrane potential (axon seg 1)
+pyNeuroML >>> INFO - Saved image to olm_example_sim_seg1_axon0-v.png of plot: Membrane potential (axon seg 1)
+
+
+../../_images/2e1bea36fe18d51db608aa0f8ab5ea17531213bda9b78245318583898b1049c5.png +../../_images/ec193126c160d9b3a694a430ec1c3ce01ff44331eb30ff5cecfa6f5b966145d2.png +../../_images/ec193126c160d9b3a694a430ec1c3ce01ff44331eb30ff5cecfa6f5b966145d2.png +../../_images/ec193126c160d9b3a694a430ec1c3ce01ff44331eb30ff5cecfa6f5b966145d2.png +../../_images/21da5d20d226f9ba010af0c85727743b7d0f604a11d927ff7b85e04705273bf6.png +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NML2_examples/SingleNeuron.html b/Userdocs/NML2_examples/SingleNeuron.html new file mode 100644 index 00000000..1a975367 --- /dev/null +++ b/Userdocs/NML2_examples/SingleNeuron.html @@ -0,0 +1,1082 @@ + + + + + + + + + + + Interactive single Izhikevich neuron NeuroML example — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Interactive single Izhikevich neuron NeuroML example#

+

To run this interactive Jupyter Notebook when viewing the online NeuroML documentation (e.g. via Binder or Google Colab), please click on the rocket icon 🚀 in the top panel. For more information, please see how to use this documentation.

+

This notebook creates a simple model in NeuroML version 2. It adds a simple spiking neuron model to a population and then the population to a network. Then we create a LEMS simulation file to specify how to to a simulate the model, and finally we execute it using jNeuroML. The results of that simulation are plotted below.

+
+NeuroML Simulation Plot +
+

See also a more detailed introduction to NeuroML and LEMS using this example.

+
+

1) Initial setup and library installs#

+

Please uncomment the line below if you use the Google Colab (it does not include these packages by default).

+
+
+
#%pip install pyneuroml neuromllite NEURON
+
+
+
+
+
+
+
from neuroml import NeuroMLDocument
+import neuroml.writers as writers
+from neuroml.utils import component_factory
+from neuroml.utils import validate_neuroml2
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+import numpy as np
+
+
+
+
+
+
+

2) Declaring the NeuroML model#

+
+

Create a NeuroML document#

+

This is the container document to which the cells and the network will be added.

+
+
+
nml_doc = component_factory(NeuroMLDocument, id="IzhSingleNeuron")
+
+
+
+
+
+
+

Define the Izhikevich cell and add it to the model#

+

The Izhikevich model is a simple, 2 variable neuron model exhibiting a range of neurophysiologically realistic spiking behaviours depending on the parameters given. We use the izhikevich2007cell version here.

+
+
+
izh0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
+
+
+
+
+
+
+

Create a network and add it to the model#

+

We add a network to the document created above.

+
+
+
net = nml_doc.add("Network", id="IzNet", validate=False)
+
+
+
+
+
+
+

Create a population of defined cells and add it to the model#

+

A population of size 1 of these cells is created and then added to the network.

+
+
+
size0 = 1
+pop0 = net.add("Population", id="IzhPop0", component=izh0.id, size=size0)
+
+
+
+
+
+
+

Define an external stimulus and add it to the model#

+

On its own the cell will not spike, so we add a small current to it in the form of a pulse generator which will apply a square pulse of current.

+
+
+
pg = nml_doc.add(
+    "PulseGenerator",
+    id="pulseGen_%i" % 0, delay="0ms", duration="1000ms",
+    amplitude="0.07 nA"
+)
+exp_input = net.add("ExplicitInput", target="%s[%i]" % (pop0.id, 0), input=pg.id)
+
+
+
+
+
+
+
+

3) Write, print and validate the generated file#

+
+

Write the NeuroML model to a file#

+
+
+
nml_file = 'izhikevich2007_single_cell_network.nml'
+writers.NeuroMLWriter.write(nml_doc, nml_file)
+print("Written network file to: " + nml_file)
+
+
+
+
+
Written network file to: izhikevich2007_single_cell_network.nml
+
+
+
+
+
+ +
+

Validate the NeuroML model#

+
+
+
validate_neuroml2(nml_file)
+
+
+
+
+
It's valid!
+
+
+
+
+
+
+
+

4) Simulating the model#

+
+

Create a simulation instance of the model#

+

The NeuroML file does not contain any information on how long to simulate the model for or what to save etc. For this we will need a LEMS simulation file.

+
+
+
simulation_id = "example-single-izhikevich2007cell-sim"
+simulation = LEMSSimulation(sim_id=simulation_id,
+                            duration=1000, dt=0.1, simulation_seed=123)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+
+
+
+
pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/izhikevich2007_single_cell_network.nml
+
+
+
+
+
+
+

Define the output file to store simulation outputs#

+

Here, we record the neuron’s membrane potential to the specified data file.

+
+
+
simulation.create_output_file(
+    "output0", "%s.v.dat" % simulation_id
+)
+simulation.add_column_to_output_file("output0", 'IzhPop0[0]', 'IzhPop0[0]/v')
+
+
+
+
+
+
+

Save the simulation to a file#

+
+
+
lems_simulation_file = simulation.save_to_file()
+with open(lems_simulation_file) as f: 
+   print(f.read())
+
+
+
+
+
<Lems>
+
+    <!-- 
+
+        This LEMS file has been automatically generated using PyNeuroML v1.1.10 (libNeuroML v0.5.8)
+
+     -->
+
+    <!-- Specify which component to run -->
+    <Target component="example-single-izhikevich2007cell-sim"/>
+
+    <!-- Include core NeuroML2 ComponentType definitions -->
+    <Include file="Cells.xml"/>
+    <Include file="Networks.xml"/>
+    <Include file="Simulation.xml"/>
+
+    <Include file="izhikevich2007_single_cell_network.nml"/>
+
+    <Simulation id="example-single-izhikevich2007cell-sim" length="1000ms" step="0.1ms" target="IzNet" seed="123">  <!-- Note seed: ensures same random numbers used every run -->
+        <OutputFile id="output0" fileName="example-single-izhikevich2007cell-sim.v.dat">
+            <OutputColumn id="IzhPop0[0]" quantity="IzhPop0[0]/v"/>
+        </OutputFile>
+
+    </Simulation>
+
+</Lems>
+
+
+
+
+
+
+
+

Run the simulation using the jNeuroML simulator#

+
+
+
pynml.run_lems_with_jneuroml(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+
+
+
+
pyNeuroML >>> INFO - Loading LEMS file: LEMS_example-single-izhikevich2007cell-sim.xml and running with jNeuroML
+pyNeuroML >>> INFO - Executing: (java -Xmx2G  -Djava.awt.headless=true -jar  "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar"  LEMS_example-single-izhikevich2007cell-sim.xml  -nogui -I '') in directory: .
+pyNeuroML >>> INFO - Command completed successfully!
+
+
+
True
+
+
+
+
+
+
+

Plot the recorded data#

+
+
+
# Load the data from the file and plot the graph for the membrane potential
+# using the pynml generate_plot utility function.
+data_array = np.loadtxt("%s.v.dat" % simulation_id)
+pynml.generate_plot(
+    [data_array[:, 0]], [data_array[:, 1]],
+    "Membrane potential", show_plot_already=True,
+    xaxis="time (s)", yaxis="membrane potential (V)",
+    save_figure_to="SingleNeuron.png"
+    
+)
+
+
+
+
+
pyNeuroML >>> INFO - Generating plot: Membrane potential
+pyNeuroML >>> INFO - Saving image to /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SingleNeuron.png of plot: Membrane potential
+pyNeuroML >>> INFO - Saved image to SingleNeuron.png of plot: Membrane potential
+
+
+../../_images/b6da95dd80b21f297a7f10e0e0d2a1138c26f6aaa4a683d91e4e0827969083ac.png +
<Axes: xlabel='time (s)', ylabel='membrane potential (V)'>
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NeuroMLv1.html b/Userdocs/NeuroMLv1.html new file mode 100644 index 00000000..01db8706 --- /dev/null +++ b/Userdocs/NeuroMLv1.html @@ -0,0 +1,719 @@ + + + + + + + + + + + NeuroML v1 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML v1

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

NeuroML v1#

+
+

Warning

+

NeuroML v1.x is deprecated. This page is maintained for archival purposes only.

+

Please use NeuroML v2.

+

neuroConstruct can be used for converting NeuroML v1 models into NeuroML v2.

+
+

There are three Levels of compliance to the NeuroML v1 specifications:

+
+

Level 1#

+ +

Any Level 1 NeuroML v1 file will also be compliant to this schema.

+
+
+

Level 2#

+ +

Any Level 1 or Level 2 NeuroML v1 file will also be compliant to this schema.

+
+
+

Level 3#

+ +

Any Level 1 or Level 2 or Level 3 NeuroML v1 file will also be compliant to this schema.

+

These files are archived in this GitHub repository.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NeuroMLv2.html b/Userdocs/NeuroMLv2.html new file mode 100644 index 00000000..c12559f8 --- /dev/null +++ b/Userdocs/NeuroMLv2.html @@ -0,0 +1,706 @@ + + + + + + + + + + + NeuroML v2 — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML v2

+ +
+
+ +
+
+
+ + + + +
+ +
+

NeuroML v2#

+

The current stable version of NeuroML is v2.3, and the XSD Schema for this can be found here. +The following figure, taken from Cannon et al. 2014 ([CGC+14]) shows some of the core elements defined in NeuroML version 2 (note: these key elements haven’t changed since that publication).

+
+Elements defined in the NeuroML schema, version 2. +
+

Fig. 57 Elements defined in the NeuroML schema, version 2.#

+
+
+ +

You can see the complete definitions of NeuroML 2 entities in the following pages. +You can also search this documentation for specific entities that you may be using in your NeuroML models.

+

Examples of files using the NeuroML 2 schema, and some of the elements they use are:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Example file

NeuroML elements used

A simple cell with a morphology & segments arranged into groups

<cell>, <morphology>, <segment>, <segmentGroup>

A cell specifying biophysical properties (channel densities, passive electrical properties, etc.)

<membraneProperties>, <intracellularProperties>, <channelDensity>

A simple HH Na+ channel

<ionChannelHH>, <gateHHrates>, <HHExpLinearRate>

Some of the simplified spiking neuron models which are supported

<iafCell>, <izhikevich2007Cell>, <adExIaFCell>, <fitzHughNagumoCell>

Synapse models

<alphaSynapse>, <expTwoSynapse>, <blockingPlasticSynapse>, <doubleSynapse>

A network of cells positioned in 3D and synaptically connected

<network>, <population>, <projection>, <connection>, <inputList>

+

NeuroML files containing the XML representation of the model can be validated to ensure all of the correct tags/attributes are present.

+

But how do we know how the model is actually meant to use the specified attributes in an element? The schema only says that leakReversal, thresh, etc. are allowed attributes on iafCell, but how are these used to calculate the membrane potential? The answer lies in another, lower-level language, called LEMS (Low Entropy Model Specification).

+

While valid NeuroML entities are contained in the schema, their underlying mathematical structure and composition rules must also be defined. +For this, NeuroML version 2 makes use of LEMS.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/NeuroMLv2AndLEMS.html b/Userdocs/NeuroMLv2AndLEMS.html new file mode 100644 index 00000000..80eb34de --- /dev/null +++ b/Userdocs/NeuroMLv2AndLEMS.html @@ -0,0 +1,827 @@ + + + + + + + + + + + NeuroML 2 and LEMS — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML 2 and LEMS

+ +
+ +
+
+ + + + +
+ +
+

NeuroML 2 and LEMS#

+

LEMS is an XML based language originally developed by Robert Cannon for specifying generic models of hybrid dynamical systems. Models defined in LEMS can also be simulated directly through a native interpreter.

+
    +
  • ComponentType elements define the behaviour of a specific type of model and specify Parameters, StateVariables, and their Dynamics and Structure can be defined as templates for model elements (e.g. HH ion channels, abstract cells, etc.). The notion of a ComponentType is thus similar to that of a class in object oriented programming.

  • +
  • Components are instances of these types, with specific values of Parameters (e.g. HH squid axon Na+ channel, I&F cell with threshold -60mV, etc.). Components play the same role as objects in object oriented programming.

  • +
+
+Figure showing relationship between LEMS and NeuroML2
+

Fig. 59 This image (from Blundell et al. 2018 ([BBC+18])) shows the usage of LEMS ComponentTypes and Components in NeuroML. +Elements in NeuroML v2 are Components which have a corresponding structural and mathematical definition in LEMS ComponentTypes.#

+
+
+

On the left side of the figure, examples are shown of the (truncated) XML representations of:

+ +

On the right, the definition of the structure and dynamics of these elements in the LEMS language is shown. +Each element has a corresponding ComponentType definition, describing the parameters (as well as their dimensions, not shown) and the dynamics in terms of state variables and their derivatives, any derived variables, and the behaviour when certain conditions are met or events are received (for example, the emission of a spike after a given threshold is crossed).

+
+

NeuroML 2 Component Type definitions in LEMS#

+

The standard set of ComponentType definitions for the core NeuroML2 elements are contained in a curated set of files (below) though users are free to define their own ComponentTypes to extend the scope of the language.

+ +

Here, for example, the izhikevich2007Cell is defined in the NeuroML schema as having the following internal attributes:

+
<xs:complexType name="Izhikevich2007Cell">
+    <xs:complexContent>
+        <xs:extension base="BaseCellMembPotCap">
+            <xs:attribute name="v0" type="Nml2Quantity_voltage" use="required"/>
+            <xs:attribute name="k" type="Nml2Quantity_conductancePerVoltage" use="required"/>
+            <xs:attribute name="vr" type="Nml2Quantity_voltage" use="required"/>
+            <xs:attribute name="vt" type="Nml2Quantity_voltage" use="required"/>
+            <xs:attribute name="vpeak" type="Nml2Quantity_voltage" use="required"/>
+            <xs:attribute name="a" type="Nml2Quantity_pertime" use="required"/>
+            <xs:attribute name="b" type="Nml2Quantity_conductance" use="required"/>
+            <xs:attribute name="c" type="Nml2Quantity_voltage" use="required"/>
+            <xs:attribute name="d" type="Nml2Quantity_current" use="required"/>
+        </xs:extension>
+    </xs:complexContent>
+</xs:complexType>
+
+
+

Correspondingly, its ComponentType dynamics are defined in the LEMS file, Cells.xml. +(Note: you do not need to read the XML LEMS definitions, you can see this information in a well formatted form here in the documentation itself)

+
<ComponentType name="izhikevich2007Cell"
+    extends="baseCellMembPotCap"
+    description="Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press">
+
+    <Parameter name="v0" dimension="voltage"/>
+
+    <!--
+    Defined in baseCellMembPotCap:
+    <Parameter name="C" dimension="capacitance"/>
+    -->
+    <Parameter name="k" dimension="conductance_per_voltage"/>
+
+    <Parameter name="vr" dimension="voltage"/>
+    <Parameter name="vt" dimension="voltage"/>
+    <Parameter name="vpeak" dimension="voltage"/>
+
+    <Parameter name="a" dimension="per_time"/>
+    <Parameter name="b" dimension="conductance"/>
+    <Parameter name="c" dimension="voltage"/>
+    <Parameter name="d" dimension="current"/>
+
+    <Attachments name="synapses" type="basePointCurrent"/>
+
+    <Exposure name="u" dimension="current"/>
+
+    <Dynamics>
+
+        <StateVariable name="v" dimension="voltage" exposure="v"/>
+        <StateVariable name="u" dimension="current" exposure="u"/>
+
+        <DerivedVariable name="iSyn"  dimension="current" exposure="iSyn" select="synapses[*]/i" reduce="add" />
+
+        <DerivedVariable name="iMemb" dimension="current" exposure="iMemb" value="k * (v-vr) * (v-vt) + iSyn - u"/>
+
+        <TimeDerivative variable="v" value="iMemb / C"/>
+        <TimeDerivative variable="u" value="a * (b * (v-vr) - u)"/>
+
+        <OnStart>
+            <StateAssignment variable="v" value="v0"/>
+            <StateAssignment variable="u" value="0"/>
+        </OnStart>
+
+        <OnCondition test="v .gt. vpeak">
+            <StateAssignment variable="v" value="c"/>
+            <StateAssignment variable="u" value="u + d"/>
+            <EventOut port="spike"/>
+        </OnCondition>
+
+    </Dynamics>
+
+</ComponentType>
+
+
+

We can define Components of the izhikevich2007Cell ComponentType with the parameters we need. For example, the izhikevich2007Cell neuron model can exhibit different spiking behaviours, so we can define a regular spiking Component, or another Component that exhibits bursting.

+
<izhikevich2007Cell id="iz2007RS" v0 = "-60mV" C="100 pF" k = "0.7 nS_per_mV"
+                    vr = "-60 mV" vt = "-40 mV" vpeak = "35 mV"
+                    a = "0.03 per_ms" b = "-2 nS" c = "-50 mV" d = "100 pA"/>
+
+
+

Once these Components are defined in the NeuroML document, we can use Instances of them to create populations and networks, and so on.

+
+

You don’t have to write in XML…

+

A quick reminder that while XML files can be edited in a standard text editor, you generally don’t have to create/update them by hand. This guide goes through the steps of creating an example using the izhikevich2007Cell model in Python using libNeuroML and pyNeuroML

+
+

Using LEMS to specify the core of NeuroML version 2 has the following significant advantages:

+
    +
  • NeuroML 2 XML files can be used standalone by applications (exported/imported) in the same way as NeuroML v1.x, without reference to the LEMS definitions, easing the transition for v1.x compliant applications

  • +
  • Any NeuroML 2 ComponentType can be extended and will be usable/translatable by any application (e.g. jLEMS) which understands LEMS

  • +
+

The first point above means that a parsing application does not necessarily have to natively read the LEMS type definition for, e.g. an izhikevich2007Cell element: it just has to map the NeuroML element parameters onto its own object model implementing that entity. +Ideally, the behaviour should be the same − which could be ascertained by testing against the reference LEMS interpreter implementation (jLEMS).

+

The second point above means that if an application does support LEMS, it can automatically parse (and generate code for) a wide range of NeuroML 2 cells, channels and synapses, including any new ComponentType derived from these, without having to natively know anything about channels, cell models, etc.

+
+

jnml and pynml handle both LEMS and NeuroML 2.

+

jNeuroML and pynml handle both LEMS and NeuroML 2. +They bundle jLEMS together with the LEMS definitions for NeuroML 2 ComponentTypes, and can simulate any LEMS model as well as many NeuroML 2 models.

+
+
+
+

More information#

+

While the tutorials cover many of the key points of using LEMS with NeuroML, there are some points which require further explanation:

+ +
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/OptimisingNeuroMLModels.html b/Userdocs/OptimisingNeuroMLModels.html new file mode 100644 index 00000000..ea35d735 --- /dev/null +++ b/Userdocs/OptimisingNeuroMLModels.html @@ -0,0 +1,2568 @@ + + + + + + + + + + + Optimising/fitting NeuroML Models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Optimising/fitting NeuroML Models#

+

pyNeuroML includes the NeuroMLTuner module for the tuning and optimisation of NeuroML models against provided data. +This uses the Neurotune Python package for the fitting of models using evolutionary computation.

+

This page will walk through an example model optimisation.

+
+
+
+
+
+Membrane potential from example experimental data. +
+

Fig. 45 Membrane potential from the experimental data.#

+
+
+
+
+
+
+
+Membrane potential obtained from example fitted model. +
+

Fig. 46 Membrane potential obtained from the model with highest fitness.#

+
+
+
+
+
+
+

The Python script used to run the optimisation and generate the graphs is given below. +This can be adapted for other optimisations.

+
#!/usr/bin/env python3
+"""
+Example file showing the tuning of an Izhikevich neuron using pyNeuroML.
+
+File: source/Userdocs/NML2_examples/tune-izhikevich.py
+
+Copyright 2023 NeuroML contributors
+"""
+
+
+from pyneuroml.tune.NeuroMLTuner import run_optimisation
+import pynwb  # type: ignore
+import numpy as np
+from pyelectro.utils import simple_network_analysis
+from typing import List, Dict, Tuple
+from pyneuroml.pynml import write_neuroml2_file
+from pyneuroml.pynml import generate_plot
+from pyneuroml.pynml import run_lems_with_jneuroml
+from neuroml import (
+    NeuroMLDocument,
+    Izhikevich2007Cell,
+    PulseGenerator,
+    Network,
+    Population,
+    ExplicitInput,
+)
+from hdmf.container import Container
+from pyneuroml.lems.LEMSSimulation import LEMSSimulation
+
+import sys
+
+
+def get_data_metrics(datafile: Container) -> Tuple[Dict, Dict, Dict]:
+    """Analyse the data to get metrics to tune against.
+
+    :returns: metrics from pyelectro analysis, currents, and the membrane potential values
+
+    """
+    analysis_results = {}
+    currents = {}
+    memb_vals = {}
+    total_acquisitions = len(datafile.acquisition)
+
+    for acq in range(1, total_acquisitions):
+        print("Going over acquisition # {}".format(acq))
+
+        # stimulus lasts about 1000ms, so we take about the first 1500 ms
+        data_v = (
+            datafile.acquisition["CurrentClampSeries_{:02d}".format(acq)].data[:15000] * 1000.0
+        )
+        # get sampling rate from the data
+        sampling_rate = datafile.acquisition[
+            "CurrentClampSeries_{:02d}".format(acq)
+        ].rate
+        # generate time steps from sampling rate
+        data_t = np.arange(0, len(data_v) / sampling_rate, 1.0 / sampling_rate) * 1000.0
+        # run the analysis
+        analysis_results[acq] = simple_network_analysis({acq: data_v}, data_t)
+
+        # extract current from description, but can be extracted from other
+        # locations also, such as the CurrentClampStimulus series.
+        data_i = (
+            datafile.acquisition["CurrentClampSeries_{:02d}".format(acq)]
+            .description.split("(")[1]
+            .split("~")[1]
+            .split(" ")[0]
+        )
+        currents[acq] = data_i
+        memb_vals[acq] = (data_t, data_v)
+
+    return (analysis_results, currents, memb_vals)
+
+
+def tune_izh_model(acq_list: List, metrics_from_data: Dict, currents: Dict) -> Dict:
+    """Tune networks model against the data.
+
+    Here we generate a network with the necessary number of Izhikevich cells,
+    one for each current stimulus, and tune them against the experimental data.
+
+    :param acq_list: list of indices of acquisitions/sweeps to tune against
+    :type acq_list: list
+    :param metrics_from_data: dictionary with the sweep number as index, and
+        the dictionary containing metrics generated from the analysis
+    :type metrics_from_data: dict
+    :param currents: dictionary with sweep number as index and stimulus current
+        value
+    """
+
+    # length of simulation of the cells---should match the length of the
+    # experiment
+    sim_time = 1500.0
+    # Create a NeuroML template network simulation file that we will use for
+    # the tuning
+    template_doc = NeuroMLDocument(id="IzhTuneNet")
+    # Add an Izhikevich cell with some parameters to the document
+    template_doc.izhikevich2007_cells.append(
+        Izhikevich2007Cell(
+            id="Izh2007",
+            C="100pF",
+            v0="-60mV",
+            k="0.7nS_per_mV",
+            vr="-60mV",
+            vt="-40mV",
+            vpeak="35mV",
+            a="0.03per_ms",
+            b="-2nS",
+            c="-50.0mV",
+            d="100pA",
+        )
+    )
+    template_doc.networks.append(Network(id="Network0"))
+    # Add a cell for each acquisition list
+    popsize = len(acq_list)
+    template_doc.networks[0].populations.append(
+        Population(id="Pop0", component="Izh2007", size=popsize)
+    )
+
+    # Add a current source for each cell, matching the currents that
+    # were used in the experimental study.
+    counter = 0
+    for acq in acq_list:
+        template_doc.pulse_generators.append(
+            PulseGenerator(
+                id="Stim{}".format(counter),
+                delay="80ms",
+                duration="1000ms",
+                amplitude="{}pA".format(currents[acq]),
+            )
+        )
+        template_doc.networks[0].explicit_inputs.append(
+            ExplicitInput(
+                target="Pop0[{}]".format(counter), input="Stim{}".format(counter)
+            )
+        )
+        counter = counter + 1
+
+    # Print a summary
+    print(template_doc.summary())
+
+    # Write to a neuroml file and validate it.
+    reference = "TuneIzhFergusonPyr3"
+    template_filename = "{}.net.nml".format(reference)
+    write_neuroml2_file(template_doc, template_filename, validate=True)
+
+    # Now for the tuning bits
+
+    # format is type:id/variable:id/units
+    # supported types: cell/channel/izhikevich2007cell
+    # supported variables:
+    #  - channel: vShift
+    #  - cell: channelDensity, vShift_channelDensity, channelDensityNernst,
+    #  erev_id, erev_ion, specificCapacitance, resistivity
+    #  - izhikevich2007Cell: all available attributes
+
+    # we want to tune these parameters within these ranges
+    # param: (min, max)
+    parameters = {
+        "izhikevich2007Cell:Izh2007/C/pF": (100, 300),
+        "izhikevich2007Cell:Izh2007/k/nS_per_mV": (0.01, 2),
+        "izhikevich2007Cell:Izh2007/vr/mV": (-70, -50),
+        "izhikevich2007Cell:Izh2007/vt/mV": (-60, 0),
+        "izhikevich2007Cell:Izh2007/vpeak/mV": (35, 70),
+        "izhikevich2007Cell:Izh2007/a/per_ms": (0.001, 0.4),
+        "izhikevich2007Cell:Izh2007/b/nS": (-10, 10),
+        "izhikevich2007Cell:Izh2007/c/mV": (-65, -10),
+        "izhikevich2007Cell:Izh2007/d/pA": (50, 500),
+    }  # type: Dict[str, Tuple[float, float]]
+
+    # Set up our target data and so on
+    ctr = 0
+    target_data = {}
+    weights = {}
+    for acq in acq_list:
+        # data to fit to:
+        # format: path/to/variable:metric
+        # metric from pyelectro, for example:
+        # https://pyelectro.readthedocs.io/en/latest/pyelectro.html?highlight=mean_spike_frequency#pyelectro.analysis.mean_spike_frequency
+        mean_spike_frequency = "Pop0[{}]/v:mean_spike_frequency".format(ctr)
+        average_last_1percent = "Pop0[{}]/v:average_last_1percent".format(ctr)
+        first_spike_time = "Pop0[{}]/v:first_spike_time".format(ctr)
+
+        # each metric can have an associated weight
+        weights[mean_spike_frequency] = 1
+        weights[average_last_1percent] = 1
+        weights[first_spike_time] = 1
+
+        # value of the target data from our data set
+        target_data[mean_spike_frequency] = metrics_from_data[acq][
+            "{}:mean_spike_frequency".format(acq)
+        ]
+        target_data[average_last_1percent] = metrics_from_data[acq][
+            "{}:average_last_1percent".format(acq)
+        ]
+        target_data[first_spike_time] = metrics_from_data[acq][
+            "{}:first_spike_time".format(acq)
+        ]
+
+        # only add these if the experimental data includes them
+        # these are only generated for traces with spikes
+        if "{}:average_maximum".format(acq) in metrics_from_data[acq]:
+            average_maximum = "Pop0[{}]/v:average_maximum".format(ctr)
+            weights[average_maximum] = 1
+            target_data[average_maximum] = metrics_from_data[acq][
+                "{}:average_maximum".format(acq)
+            ]
+        if "{}:average_minimum".format(acq) in metrics_from_data[acq]:
+            average_minimum = "Pop0[{}]/v:average_minimum".format(ctr)
+            weights[average_minimum] = 1
+            target_data[average_minimum] = metrics_from_data[acq][
+                "{}:average_minimum".format(acq)
+            ]
+
+        ctr = ctr + 1
+
+    # simulator to use
+    simulator = "jNeuroML"
+
+    return run_optimisation(
+        # Prefix for new files
+        prefix="TuneIzh",
+        # Name of the NeuroML template file
+        neuroml_file=template_filename,
+        # Name of the network
+        target="Network0",
+        # Parameters to be fitted
+        parameters=list(parameters.keys()),
+        # Our max and min constraints
+        min_constraints=[v[0] for v in parameters.values()],
+        max_constraints=[v[1] for v in parameters.values()],
+        # Weights we set for parameters
+        weights=weights,
+        # The experimental metrics to fit to
+        target_data=target_data,
+        # Simulation time
+        sim_time=sim_time,
+        # EC parameters
+        population_size=100,
+        max_evaluations=500,
+        num_selected=30,
+        num_offspring=50,
+        mutation_rate=0.9,
+        num_elites=3,
+        # Seed value
+        seed=12345,
+        # Simulator
+        simulator=simulator,
+        dt=0.025,
+        show_plot_already='-nogui' not in sys.argv,
+        save_to_file="fitted_izhikevich_fitness.png",
+        save_to_file_scatter="fitted_izhikevich_scatter.png",
+        save_to_file_hist="fitted_izhikevich_hist.png",
+        save_to_file_output="fitted_izhikevich_output.png",
+        num_parallel_evaluations=4,
+    )
+
+
+def run_fitted_cell_simulation(
+    sweeps_to_tune_against: List, tuning_report: Dict, simulation_id: str
+) -> None:
+    """Run a simulation with the values obtained from the fitting
+
+    :param tuning_report: tuning report from the optimser
+    :type tuning_report: Dict
+    :param simulation_id: text id of simulation
+    :type simulation_id: str
+
+    """
+    # get the fittest variables
+    fittest_vars = tuning_report["fittest vars"]
+    C = str(fittest_vars["izhikevich2007Cell:Izh2007/C/pF"]) + "pF"
+    k = str(fittest_vars["izhikevich2007Cell:Izh2007/k/nS_per_mV"]) + "nS_per_mV"
+    vr = str(fittest_vars["izhikevich2007Cell:Izh2007/vr/mV"]) + "mV"
+    vt = str(fittest_vars["izhikevich2007Cell:Izh2007/vt/mV"]) + "mV"
+    vpeak = str(fittest_vars["izhikevich2007Cell:Izh2007/vpeak/mV"]) + "mV"
+    a = str(fittest_vars["izhikevich2007Cell:Izh2007/a/per_ms"]) + "per_ms"
+    b = str(fittest_vars["izhikevich2007Cell:Izh2007/b/nS"]) + "nS"
+    c = str(fittest_vars["izhikevich2007Cell:Izh2007/c/mV"]) + "mV"
+    d = str(fittest_vars["izhikevich2007Cell:Izh2007/d/pA"]) + "pA"
+
+    # Create a simulation using our obtained parameters.
+    # Note that the tuner generates a graph with the fitted values already, but
+    # we want to keep a copy of our fitted cell also, so we'll create a NeuroML
+    # Document ourselves also.
+    sim_time = 1500.0
+    simulation_doc = NeuroMLDocument(id="FittedNet")
+    # Add an Izhikevich cell with some parameters to the document
+    simulation_doc.izhikevich2007_cells.append(
+        Izhikevich2007Cell(
+            id="Izh2007",
+            C=C,
+            v0="-60mV",
+            k=k,
+            vr=vr,
+            vt=vt,
+            vpeak=vpeak,
+            a=a,
+            b=b,
+            c=c,
+            d=d,
+        )
+    )
+    simulation_doc.networks.append(Network(id="Network0"))
+    # Add a cell for each acquisition list
+    popsize = len(sweeps_to_tune_against)
+    simulation_doc.networks[0].populations.append(
+        Population(id="Pop0", component="Izh2007", size=popsize)
+    )
+
+    # Add a current source for each cell, matching the currents that
+    # were used in the experimental study.
+    counter = 0
+    for acq in sweeps_to_tune_against:
+        simulation_doc.pulse_generators.append(
+            PulseGenerator(
+                id="Stim{}".format(counter),
+                delay="80ms",
+                duration="1000ms",
+                amplitude="{}pA".format(currents[acq]),
+            )
+        )
+        simulation_doc.networks[0].explicit_inputs.append(
+            ExplicitInput(
+                target="Pop0[{}]".format(counter), input="Stim{}".format(counter)
+            )
+        )
+        counter = counter + 1
+
+    # Print a summary
+    print(simulation_doc.summary())
+
+    # Write to a neuroml file and validate it.
+    reference = "FittedIzhFergusonPyr3"
+    simulation_filename = "{}.net.nml".format(reference)
+    write_neuroml2_file(simulation_doc, simulation_filename, validate=True)
+
+    simulation = LEMSSimulation(
+        sim_id=simulation_id,
+        duration=sim_time,
+        dt=0.1,
+        target="Network0",
+        simulation_seed=54321,
+    )
+    simulation.include_neuroml2_file(simulation_filename)
+    simulation.create_output_file("output0", "{}.v.dat".format(simulation_id))
+    counter = 0
+    for acq in sweeps_to_tune_against:
+        simulation.add_column_to_output_file(
+            "output0", "Pop0[{}]".format(counter), "Pop0[{}]/v".format(counter)
+        )
+        counter = counter + 1
+    simulation_file = simulation.save_to_file()
+    # simulate
+    run_lems_with_jneuroml(simulation_file, max_memory="2G", nogui=True, plot=False)
+
+
+def plot_sim_data(
+    sweeps_to_tune_against: List, simulation_id: str, memb_pots: Dict
+) -> None:
+    """Plot data from our fitted simulation
+
+    :param simulation_id: string id of simulation
+    :type simulation_id: str
+    """
+    # Plot
+    data_array = np.loadtxt("%s.v.dat" % simulation_id)
+
+    # construct data for plotting
+    counter = 0
+    time_vals_list = []
+    sim_v_list = []
+    data_v_list = []
+    data_t_list = []
+    stim_vals = []
+    for acq in sweeps_to_tune_against:
+        stim_vals.append("{}pA".format(currents[acq]))
+
+        # remains the same for all columns
+        time_vals_list.append(data_array[:, 0] * 1000.0)
+        sim_v_list.append(data_array[:, counter + 1] * 1000.0)
+
+        data_v_list.append(memb_pots[acq][1])
+        data_t_list.append(memb_pots[acq][0])
+
+        counter = counter + 1
+
+    # Model membrane potential plot
+    generate_plot(
+        xvalues=time_vals_list,
+        yvalues=sim_v_list,
+        labels=stim_vals,
+        title="Membrane potential (model)",
+        show_plot_already=False,
+        save_figure_to="%s-model-v.png" % simulation_id,
+        xaxis="time (ms)",
+        yaxis="membrane potential (mV)",
+    )
+    # data membrane potential plot
+    generate_plot(
+        xvalues=data_t_list,
+        yvalues=data_v_list,
+        labels=stim_vals,
+        title="Membrane potential (exp)",
+        show_plot_already=False,
+        save_figure_to="%s-exp-v.png" % simulation_id,
+        xaxis="time (ms)",
+        yaxis="membrane potential (mV)",
+    )
+
+
+if __name__ == "__main__":
+
+    # set the default size for generated plots
+    # https://matplotlib.org/stable/tutorials/introductory/customizing.html#a-sample-matplotlibrc-file
+    import matplotlib as mpl
+    mpl.rcParams["figure.figsize"] = [18, 12]
+
+    io = pynwb.NWBHDF5IO("./FergusonEtAl2015_PYR3.nwb", "r")
+    datafile = io.read()
+
+    analysis_results, currents, memb_pots = get_data_metrics(datafile)
+
+    # Choose what sweeps to tune against.
+    # There are 33 sweeps: 1..33.
+    # sweeps_to_tune_against = [1, 2, 15, 30, 31, 32, 33]
+    sweeps_to_tune_against = [16,21]
+    report = tune_izh_model(sweeps_to_tune_against, analysis_results, currents)
+
+    simulation_id = "fitted_izhikevich_sim"
+    run_fitted_cell_simulation(sweeps_to_tune_against, report, simulation_id)
+
+    plot_sim_data(sweeps_to_tune_against, simulation_id, memb_pots)
+
+    # close the data file
+    io.close()
+
+
+
+

Loading data and calculating metrics to use for optimisation#

+

The first step in the optimisation of the model is to obtain the data that the model is to be fitted against. +In this example, we will use the data set of CA1 pyramidal cell recordings using an intact whole hippocampus preparation, including recordings of rebound firing [FHA+15]. +The data set is provided in the Neurodata Without Borders (NWB) format. +It can can be downloaded here on the Open Source Brain repository, and can also be viewed on the NWB Explorer web application:

+
+Screenshot showing two recordings from FergusonEtAl2015_PYR3.nwb in NWB Explorer. +
+

Fig. 47 Screenshot showing two recordings from FergusonEtAl2015_PYR3.nwb in NWB Explorer.#

+
+
+

For this example, we will use the FergusonEtAl2015_PYR3.nwb data file. +We use the PyNWB package to read it, and then pass the loaded data to our get_data_metrics function to extract the metrics we want to use for model fitting.

+
    io = pynwb.NWBHDF5IO("./FergusonEtAl2015_PYR3.nwb", "r")
+    datafile = io.read()
+
+    analysis_results, currents, memb_pots = get_data_metrics(datafile)
+
+
+

Similar to libNeuroML, PyNWB provides a Python object model to interact with NWB files. +You can learn more on using PyNWB in its documentation.

+

Here, the data file includes recordings from multiple (33 in total) current clamp experiments that are numbered from 1 through 33. +We iterate over each recording individually to extract the membrane potential values and store them in data_v. +For each, we also calculate the time stamps for the recordings from the provided sampling rate. +We pass this information to the simple_network_analysis function provided by the PyElectro Python package to calculate features (metrics) that we will use for fitting a neuron model.

+
def get_data_metrics(datafile: Container) -> Tuple[Dict, Dict, Dict]:
+    """Analyse the data to get metrics to tune against.
+
+    :returns: metrics from pyelectro analysis, currents, and the membrane potential values
+
+    """
+    analysis_results = {}
+    currents = {}
+    memb_vals = {}
+    total_acquisitions = len(datafile.acquisition)
+
+    for acq in range(1, total_acquisitions):
+        print("Going over acquisition # {}".format(acq))
+
+        # stimulus lasts about 1000ms, so we take about the first 1500 ms
+        data_v = (
+            datafile.acquisition["CurrentClampSeries_{:02d}".format(acq)].data[:15000] * 1000.0
+        )
+        # get sampling rate from the data
+        sampling_rate = datafile.acquisition[
+            "CurrentClampSeries_{:02d}".format(acq)
+        ].rate
+        # generate time steps from sampling rate
+        data_t = np.arange(0, len(data_v) / sampling_rate, 1.0 / sampling_rate) * 1000.0
+        # run the analysis
+        analysis_results[acq] = simple_network_analysis({acq: data_v}, data_t)
+
+        # extract current from description, but can be extracted from other
+        # locations also, such as the CurrentClampStimulus series.
+        data_i = (
+            datafile.acquisition["CurrentClampSeries_{:02d}".format(acq)]
+            .description.split("(")[1]
+            .split("~")[1]
+            .split(" ")[0]
+        )
+        currents[acq] = data_i
+        memb_vals[acq] = (data_t, data_v)
+
+    return (analysis_results, currents, memb_vals)
+
+
+

The features calculated by PyElectro for each recording, which we store in analysis_results, can be seen below:

+
Going over acquisition # 1
+pyelectro >>> {   '1:average_last_1percent': -60.4182980855306,
+pyelectro >>>     '1:max_peak_no': 0,
+pyelectro >>>     '1:maximum': -57.922367,
+pyelectro >>>     '1:mean_spike_frequency': 0,
+pyelectro >>>     '1:min_peak_no': 0,
+pyelectro >>>     '1:minimum': -60.729984}
+Going over acquisition # 2
+pyelectro >>> {   '2:average_last_1percent': -60.2773068745931,
+pyelectro >>>     '2:max_peak_no': 0,
+pyelectro >>>     '2:maximum': -56.182865,
+pyelectro >>>     '2:mean_spike_frequency': 0,
+pyelectro >>>     '2:min_peak_no': 0,
+pyelectro >>>     '2:minimum': -60.882572}
+Going over acquisition # 3
+pyelectro >>> {   '3:average_last_1percent': -60.175174713134766,
+pyelectro >>>     '3:max_peak_no': 0,
+pyelectro >>>     '3:maximum': -54.22974,
+pyelectro >>>     '3:mean_spike_frequency': 0,
+pyelectro >>>     '3:min_peak_no': 0,
+pyelectro >>>     '3:minimum': -60.7605}
+Going over acquisition # 4
+pyelectro >>> {   '4:average_last_1percent': -60.11576716105143,
+pyelectro >>>     '4:max_peak_no': 0,
+pyelectro >>>     '4:maximum': -49.133305,
+pyelectro >>>     '4:mean_spike_frequency': 0,
+pyelectro >>>     '4:min_peak_no': 0,
+pyelectro >>>     '4:minimum': -60.607914}
+Going over acquisition # 5
+pyelectro >>> {   '5:average_last_1percent': -59.628299713134766,
+pyelectro >>>     '5:max_peak_no': 0,
+pyelectro >>>     '5:maximum': -48.645023,
+pyelectro >>>     '5:mean_spike_frequency': 0,
+pyelectro >>>     '5:min_peak_no': 0,
+pyelectro >>>     '5:minimum': -60.241703}
+Going over acquisition # 6
+pyelectro >>> {   '6:average_last_1percent': -60.04679743448893,
+pyelectro >>>     '6:max_peak_no': 0,
+pyelectro >>>     '6:maximum': -45.16602,
+pyelectro >>>     '6:mean_spike_frequency': 0,
+pyelectro >>>     '6:min_peak_no': 0,
+pyelectro >>>     '6:minimum': -60.699467}
+Going over acquisition # 7
+pyelectro >>> {   '7:average_last_1percent': -59.88566462198893,
+pyelectro >>>     '7:average_maximum': 66.3147,
+pyelectro >>>     '7:average_minimum': -47.9126,
+pyelectro >>>     '7:first_spike_time': 482.20000000000005,
+pyelectro >>>     '7:max_peak_no': 2,
+pyelectro >>>     '7:maximum': 67.38281,
+pyelectro >>>     '7:mean_spike_frequency': 0,
+pyelectro >>>     '7:min_peak_no': 1,
+pyelectro >>>     '7:minimum': -60.15015}
+Going over acquisition # 8
+pyelectro >>> {   '8:average_last_1percent': -60.5531857808431,
+pyelectro >>>     '8:average_maximum': 64.63623,
+pyelectro >>>     '8:average_minimum': -46.05103,
+pyelectro >>>     '8:first_spike_time': 280.8,
+pyelectro >>>     '8:max_peak_no': 2,
+pyelectro >>>     '8:maximum': 65.460205,
+pyelectro >>>     '8:mean_spike_frequency': 0,
+pyelectro >>>     '8:min_peak_no': 1,
+pyelectro >>>     '8:minimum': -61.096195}
+Going over acquisition # 9
+pyelectro >>> {   '9:average_last_1percent': -60.2797482808431,
+pyelectro >>>     '9:average_maximum': 62.187195,
+pyelectro >>>     '9:average_minimum': -45.867924,
+pyelectro >>>     '9:first_spike_time': 192.10000000000002,
+pyelectro >>>     '9:interspike_time_covar': 0.12604539832023948,
+pyelectro >>>     '9:max_interspike_time': 233.69999999999993,
+pyelectro >>>     '9:max_peak_no': 4,
+pyelectro >>>     '9:maximum': 64.42261,
+pyelectro >>>     '9:mean_spike_frequency': 4.984216647283602,
+pyelectro >>>     '9:min_interspike_time': 172.29999999999995,
+pyelectro >>>     '9:min_peak_no': 3,
+pyelectro >>>     '9:minimum': -60.91309,
+pyelectro >>>     '9:peak_decay_exponent': -0.008125577959852965,
+pyelectro >>>     '9:peak_linear_gradient': -0.007648055557429393,
+pyelectro >>>     '9:spike_broadening': 0.891046031985908,
+pyelectro >>>     '9:spike_frequency_adaptation': -0.05850411039850073,
+pyelectro >>>     '9:spike_width_adaptation': 0.02767948174212246,
+pyelectro >>>     '9:trough_decay_exponent': -0.00318728965696189,
+pyelectro >>>     '9:trough_phase_adaptation': -0.05016262394149966}
+Going over acquisition # 10
+pyelectro >>> {   '10:average_last_1percent': -60.4292844136556,
+pyelectro >>>     '10:average_maximum': 59.680183,
+pyelectro >>>     '10:average_minimum': -44.731144,
+pyelectro >>>     '10:first_spike_time': 156.9,
+pyelectro >>>     '10:interspike_time_covar': 0.5779639183148945,
+pyelectro >>>     '10:max_interspike_time': 438.5000000000001,
+pyelectro >>>     '10:max_peak_no': 5,
+pyelectro >>>     '10:maximum': 62.072758,
+pyelectro >>>     '10:mean_spike_frequency': 4.553215708594194,
+pyelectro >>>     '10:min_interspike_time': 132.60000000000005,
+pyelectro >>>     '10:min_peak_no': 4,
+pyelectro >>>     '10:minimum': -60.882572,
+pyelectro >>>     '10:peak_decay_exponent': -0.009585017031582235,
+pyelectro >>>     '10:peak_linear_gradient': -0.005260966229876463,
+pyelectro >>>     '10:spike_broadening': 0.8756680523402136,
+pyelectro >>>     '10:spike_frequency_adaptation': -0.04780471479504103,
+pyelectro >>>     '10:spike_width_adaptation': 0.014551159295128686,
+pyelectro >>>     '10:trough_decay_exponent': -0.006056437839814275,
+pyelectro >>>     '10:trough_phase_adaptation': -0.04269124477477909}
+Going over acquisition # 11
+pyelectro >>> {   '11:average_last_1percent': -60.84635798136393,
+pyelectro >>>     '11:average_maximum': 58.73414,
+pyelectro >>>     '11:average_minimum': -43.800358,
+pyelectro >>>     '11:first_spike_time': 138.1,
+pyelectro >>>     '11:interspike_time_covar': 0.18317620745649893,
+pyelectro >>>     '11:max_interspike_time': 179.9999999999999,
+pyelectro >>>     '11:max_peak_no': 5,
+pyelectro >>>     '11:maximum': 61.03516,
+pyelectro >>>     '11:mean_spike_frequency': 7.033585370142431,
+pyelectro >>>     '11:min_interspike_time': 106.50000000000003,
+pyelectro >>>     '11:min_peak_no': 4,
+pyelectro >>>     '11:minimum': -61.248783,
+pyelectro >>>     '11:peak_decay_exponent': -0.010372120562797708,
+pyelectro >>>     '11:peak_linear_gradient': -0.0074866848970347325,
+pyelectro >>>     '11:spike_broadening': 0.8498887121142943,
+pyelectro >>>     '11:spike_frequency_adaptation': -0.052381521145715274,
+pyelectro >>>     '11:spike_width_adaptation': 0.025414793671653328,
+pyelectro >>>     '11:trough_decay_exponent': -0.007552906636393599,
+pyelectro >>>     '11:trough_phase_adaptation': -0.04473631982885844}
+Going over acquisition # 12
+pyelectro >>> {   '12:average_last_1percent': -61.085208892822266,
+pyelectro >>>     '12:average_maximum': 58.481857,
+pyelectro >>>     '12:average_minimum': -42.974857,
+pyelectro >>>     '12:first_spike_time': 127.40000000000002,
+pyelectro >>>     '12:interspike_time_covar': 0.16275057704467177,
+pyelectro >>>     '12:max_interspike_time': 136.5,
+pyelectro >>>     '12:max_peak_no': 6,
+pyelectro >>>     '12:maximum': 61.737064,
+pyelectro >>>     '12:mean_spike_frequency': 8.791981712678037,
+pyelectro >>>     '12:min_interspike_time': 84.60000000000001,
+pyelectro >>>     '12:min_peak_no': 5,
+pyelectro >>>     '12:minimum': -61.462406,
+pyelectro >>>     '12:peak_decay_exponent': -0.015987075984851808,
+pyelectro >>>     '12:peak_linear_gradient': -0.009383652380440125,
+pyelectro >>>     '12:spike_broadening': 0.8205694396572242,
+pyelectro >>>     '12:spike_frequency_adaptation': -0.04259621402895674,
+pyelectro >>>     '12:spike_width_adaptation': 0.0228428573204052,
+pyelectro >>>     '12:trough_decay_exponent': -0.012180031782655684,
+pyelectro >>>     '12:trough_phase_adaptation': 0.0003391093549627843}
+Going over acquisition # 13
+pyelectro >>> {   '13:average_last_1percent': -60.6233762105306,
+pyelectro >>>     '13:average_maximum': 56.980137,
+pyelectro >>>     '13:average_minimum': -42.205814,
+pyelectro >>>     '13:first_spike_time': 122.9,
+pyelectro >>>     '13:interspike_time_covar': 0.1989630987796946,
+pyelectro >>>     '13:max_interspike_time': 138.9000000000001,
+pyelectro >>>     '13:max_peak_no': 8,
+pyelectro >>>     '13:maximum': 61.30982,
+pyelectro >>>     '13:mean_spike_frequency': 9.743875278396434,
+pyelectro >>>     '13:min_interspike_time': 75.4,
+pyelectro >>>     '13:min_peak_no': 7,
+pyelectro >>>     '13:minimum': -60.974125,
+pyelectro >>>     '13:peak_decay_exponent': -0.01856642711769415,
+pyelectro >>>     '13:peak_linear_gradient': -0.009561076077386068,
+pyelectro >>>     '13:spike_broadening': 0.803052014150605,
+pyelectro >>>     '13:spike_frequency_adaptation': -0.028079821139188187,
+pyelectro >>>     '13:spike_width_adaptation': 0.01504310702538977,
+pyelectro >>>     '13:trough_decay_exponent': -0.013208504624154408,
+pyelectro >>>     '13:trough_phase_adaptation': -0.025379665674913895}
+Going over acquisition # 14
+pyelectro >>> {   '14:average_last_1percent': -60.723270416259766,
+pyelectro >>>     '14:average_maximum': 55.986195,
+pyelectro >>>     '14:average_minimum': -41.54587,
+pyelectro >>>     '14:first_spike_time': 114.8,
+pyelectro >>>     '14:interspike_time_covar': 0.34335772265161896,
+pyelectro >>>     '14:max_interspike_time': 194.39999999999998,
+pyelectro >>>     '14:max_peak_no': 9,
+pyelectro >>>     '14:maximum': 60.882572,
+pyelectro >>>     '14:mean_spike_frequency': 8.785416209092906,
+pyelectro >>>     '14:min_interspike_time': 74.40000000000002,
+pyelectro >>>     '14:min_peak_no': 8,
+pyelectro >>>     '14:minimum': -61.126713,
+pyelectro >>>     '14:peak_decay_exponent': -0.022541304298167242,
+pyelectro >>>     '14:peak_linear_gradient': -0.008000988888256885,
+pyelectro >>>     '14:spike_broadening': 0.8009562042583951,
+pyelectro >>>     '14:spike_frequency_adaptation': -0.022434594832088855,
+pyelectro >>>     '14:spike_width_adaptation': 0.010424354074822617,
+pyelectro >>>     '14:trough_decay_exponent': -0.018754566142487872,
+pyelectro >>>     '14:trough_phase_adaptation': -0.019014319738344054}
+Going over acquisition # 15
+pyelectro >>> {   '15:average_last_1percent': -60.99833552042643,
+pyelectro >>>     '15:average_maximum': 55.89295,
+pyelectro >>>     '15:average_minimum': -40.78892,
+pyelectro >>>     '15:first_spike_time': 113.2,
+pyelectro >>>     '15:interspike_time_covar': 0.6436697297327385,
+pyelectro >>>     '15:max_interspike_time': 311.30000000000007,
+pyelectro >>>     '15:max_peak_no': 8,
+pyelectro >>>     '15:maximum': 60.91309,
+pyelectro >>>     '15:mean_spike_frequency': 8.201523140011716,
+pyelectro >>>     '15:min_interspike_time': 71.60000000000001,
+pyelectro >>>     '15:min_peak_no': 7,
+pyelectro >>>     '15:minimum': -61.370853,
+pyelectro >>>     '15:peak_decay_exponent': -0.025953113905923406,
+pyelectro >>>     '15:peak_linear_gradient': -0.008306657481016694,
+pyelectro >>>     '15:spike_broadening': 0.7782197474305453,
+pyelectro >>>     '15:spike_frequency_adaptation': -0.030010388928284993,
+pyelectro >>>     '15:spike_width_adaptation': 0.012108100430332605,
+pyelectro >>>     '15:trough_decay_exponent': -0.01262141611091244,
+pyelectro >>>     '15:trough_phase_adaptation': -0.025746376793896804}
+Going over acquisition # 16
+pyelectro >>> {   '16:average_last_1percent': -60.380863189697266,
+pyelectro >>>     '16:average_maximum': 54.52382,
+pyelectro >>>     '16:average_minimum': -39.78882,
+pyelectro >>>     '16:first_spike_time': 108.9,
+pyelectro >>>     '16:interspike_time_covar': 0.23652534644271225,
+pyelectro >>>     '16:max_interspike_time': 123.00000000000011,
+pyelectro >>>     '16:max_peak_no': 11,
+pyelectro >>>     '16:maximum': 60.7605,
+pyelectro >>>     '16:mean_spike_frequency': 10.8837614279495,
+pyelectro >>>     '16:min_interspike_time': 59.30000000000001,
+pyelectro >>>     '16:min_peak_no': 10,
+pyelectro >>>     '16:minimum': -60.79102,
+pyelectro >>>     '16:peak_decay_exponent': -0.03301104578192642,
+pyelectro >>>     '16:peak_linear_gradient': -0.007545664792227554,
+pyelectro >>>     '16:spike_broadening': 0.7546314677569799,
+pyelectro >>>     '16:spike_frequency_adaptation': -0.013692136410690963,
+pyelectro >>>     '16:spike_width_adaptation': 0.008664177864358623,
+pyelectro >>>     '16:trough_decay_exponent': -0.023836469122601508,
+pyelectro >>>     '16:trough_phase_adaptation': -0.010081239597430595}
+Going over acquisition # 17
+pyelectro >>> {   '17:average_last_1percent': -60.552982330322266,
+pyelectro >>>     '17:average_maximum': 54.44642,
+pyelectro >>>     '17:average_minimum': -39.008247,
+pyelectro >>>     '17:first_spike_time': 105.6,
+pyelectro >>>     '17:interspike_time_covar': 0.19651182311074483,
+pyelectro >>>     '17:max_interspike_time': 106.29999999999995,
+pyelectro >>>     '17:max_peak_no': 10,
+pyelectro >>>     '17:maximum': 60.63843,
+pyelectro >>>     '17:mean_spike_frequency': 11.506008693428791,
+pyelectro >>>     '17:min_interspike_time': 58.60000000000002,
+pyelectro >>>     '17:min_peak_no': 9,
+pyelectro >>>     '17:minimum': -61.03516,
+pyelectro >>>     '17:peak_decay_exponent': -0.03684157763477531,
+pyelectro >>>     '17:peak_linear_gradient': -0.009090863209461205,
+pyelectro >>>     '17:spike_broadening': 0.7534694949245309,
+pyelectro >>>     '17:spike_frequency_adaptation': -0.023373852901912264,
+pyelectro >>>     '17:spike_width_adaptation': 0.011268432654001511,
+pyelectro >>>     '17:trough_decay_exponent': -0.020590018720385343,
+pyelectro >>>     '17:trough_phase_adaptation': -0.00906121257722172}
+Going over acquisition # 18
+pyelectro >>> {   '18:average_last_1percent': -60.64799372355143,
+pyelectro >>>     '18:average_maximum': 53.783077,
+pyelectro >>>     '18:average_minimum': -38.424683,
+pyelectro >>>     '18:first_spike_time': 104.2,
+pyelectro >>>     '18:interspike_time_covar': 0.2502832189694502,
+pyelectro >>>     '18:max_interspike_time': 124.59999999999991,
+pyelectro >>>     '18:max_peak_no': 11,
+pyelectro >>>     '18:maximum': 60.63843,
+pyelectro >>>     '18:mean_spike_frequency': 11.420740063956146,
+pyelectro >>>     '18:min_interspike_time': 53.09999999999998,
+pyelectro >>>     '18:min_peak_no': 10,
+pyelectro >>>     '18:minimum': -61.03516,
+pyelectro >>>     '18:peak_decay_exponent': -0.04141134556729957,
+pyelectro >>>     '18:peak_linear_gradient': -0.008476351143979814,
+pyelectro >>>     '18:spike_broadening': 0.7403041191114148,
+pyelectro >>>     '18:spike_frequency_adaptation': -0.01809717600857398,
+pyelectro >>>     '18:spike_width_adaptation': 0.009174879706803092,
+pyelectro >>>     '18:trough_decay_exponent': -0.02760451378209885,
+pyelectro >>>     '18:trough_phase_adaptation': -0.005774543184281237}
+Going over acquisition # 19
+pyelectro >>> {   '19:average_last_1percent': -60.855106353759766,
+pyelectro >>>     '19:average_maximum': 53.430737,
+pyelectro >>>     '19:average_minimum': -37.713623,
+pyelectro >>>     '19:first_spike_time': 102.50000000000001,
+pyelectro >>>     '19:interspike_time_covar': 0.25333327224227414,
+pyelectro >>>     '19:max_interspike_time': 114.69999999999993,
+pyelectro >>>     '19:max_peak_no': 11,
+pyelectro >>>     '19:maximum': 60.607914,
+pyelectro >>>     '19:mean_spike_frequency': 12.47038284075321,
+pyelectro >>>     '19:min_interspike_time': 51.8,
+pyelectro >>>     '19:min_peak_no': 10,
+pyelectro >>>     '19:minimum': -61.248783,
+pyelectro >>>     '19:peak_decay_exponent': -0.04918301935790627,
+pyelectro >>>     '19:peak_linear_gradient': -0.008553290998046907,
+pyelectro >>>     '19:spike_broadening': 0.7301692622822238,
+pyelectro >>>     '19:spike_frequency_adaptation': -0.015561797159916213,
+pyelectro >>>     '19:spike_width_adaptation': 0.010054185105794627,
+pyelectro >>>     '19:trough_decay_exponent': -0.03413795061471875,
+pyelectro >>>     '19:trough_phase_adaptation': -0.011967671377256838}
+Going over acquisition # 20
+pyelectro >>> {   '20:average_last_1percent': -60.793460845947266,
+pyelectro >>>     '20:average_maximum': 53.11169,
+pyelectro >>>     '20:average_minimum': -37.045288,
+pyelectro >>>     '20:first_spike_time': 101.4,
+pyelectro >>>     '20:interspike_time_covar': 0.2865607615520669,
+pyelectro >>>     '20:max_interspike_time': 123.0,
+pyelectro >>>     '20:max_peak_no': 11,
+pyelectro >>>     '20:maximum': 60.51636,
+pyelectro >>>     '20:mean_spike_frequency': 12.624668602449184,
+pyelectro >>>     '20:min_interspike_time': 49.099999999999994,
+pyelectro >>>     '20:min_peak_no': 10,
+pyelectro >>>     '20:minimum': -61.30982,
+pyelectro >>>     '20:peak_decay_exponent': -0.053836942989781186,
+pyelectro >>>     '20:peak_linear_gradient': -0.009554089132365705,
+pyelectro >>>     '20:spike_broadening': 0.7067401817806985,
+pyelectro >>>     '20:spike_frequency_adaptation': -0.02046601020346991,
+pyelectro >>>     '20:spike_width_adaptation': 0.01032699280307952,
+pyelectro >>>     '20:trough_decay_exponent': -0.03229413870032492,
+pyelectro >>>     '20:trough_phase_adaptation': -0.009902402143729637}
+Going over acquisition # 21
+pyelectro >>> {   '21:average_last_1percent': -59.912113189697266,
+pyelectro >>>     '21:average_maximum': 51.912754,
+pyelectro >>>     '21:average_minimum': -35.964966,
+pyelectro >>>     '21:first_spike_time': 100.4,
+pyelectro >>>     '21:interspike_time_covar': 0.31784939578511834,
+pyelectro >>>     '21:max_interspike_time': 130.10000000000002,
+pyelectro >>>     '21:max_peak_no': 13,
+pyelectro >>>     '21:maximum': 61.15723,
+pyelectro >>>     '21:mean_spike_frequency': 12.369858777445623,
+pyelectro >>>     '21:min_interspike_time': 45.10000000000002,
+pyelectro >>>     '21:min_peak_no': 12,
+pyelectro >>>     '21:minimum': -61.614994,
+pyelectro >>>     '21:peak_decay_exponent': -0.06340663337165775,
+pyelectro >>>     '21:peak_linear_gradient': -0.009514554022982258,
+pyelectro >>>     '21:spike_broadening': 0.6805457955255507,
+pyelectro >>>     '21:spike_frequency_adaptation': -0.012321447021551269,
+pyelectro >>>     '21:spike_width_adaptation': 0.007303096579113352,
+pyelectro >>>     '21:trough_decay_exponent': -0.03236374133246423,
+pyelectro >>>     '21:trough_phase_adaptation': -0.009705621425080494}
+Going over acquisition # 22
+pyelectro >>> {   '22:average_last_1percent': -60.0850461324056,
+pyelectro >>>     '22:average_maximum': 51.325874,
+pyelectro >>>     '22:average_minimum': -35.22746,
+pyelectro >>>     '22:first_spike_time': 97.7,
+pyelectro >>>     '22:interspike_time_covar': 0.3280130255436152,
+pyelectro >>>     '22:max_interspike_time': 123.30000000000007,
+pyelectro >>>     '22:max_peak_no': 13,
+pyelectro >>>     '22:maximum': 60.91309,
+pyelectro >>>     '22:mean_spike_frequency': 12.784998934583422,
+pyelectro >>>     '22:min_interspike_time': 40.60000000000001,
+pyelectro >>>     '22:min_peak_no': 12,
+pyelectro >>>     '22:minimum': -60.51636,
+pyelectro >>>     '22:peak_decay_exponent': -0.07398649685748288,
+pyelectro >>>     '22:peak_linear_gradient': -0.008846573199048182,
+pyelectro >>>     '22:spike_broadening': 0.673572178798493,
+pyelectro >>>     '22:spike_frequency_adaptation': -0.01394751742502263,
+pyelectro >>>     '22:spike_width_adaptation': 0.00745978471908774,
+pyelectro >>>     '22:trough_decay_exponent': -0.03985576781966312,
+pyelectro >>>     '22:trough_phase_adaptation': -0.012949190338366346}
+Going over acquisition # 23
+pyelectro >>> {   '23:average_last_1percent': -60.42582575480143,
+pyelectro >>>     '23:average_maximum': 50.883705,
+pyelectro >>>     '23:average_minimum': -34.70553,
+pyelectro >>>     '23:first_spike_time': 97.0,
+pyelectro >>>     '23:interspike_time_covar': 0.3025008293643565,
+pyelectro >>>     '23:max_interspike_time': 113.00000000000011,
+pyelectro >>>     '23:max_peak_no': 14,
+pyelectro >>>     '23:maximum': 61.126713,
+pyelectro >>>     '23:mean_spike_frequency': 13.453378867846421,
+pyelectro >>>     '23:min_interspike_time': 37.599999999999994,
+pyelectro >>>     '23:min_peak_no': 13,
+pyelectro >>>     '23:minimum': -60.79102,
+pyelectro >>>     '23:peak_decay_exponent': -0.09454776279913378,
+pyelectro >>>     '23:peak_linear_gradient': -0.007913299554316041,
+pyelectro >>>     '23:spike_broadening': 0.6664213397577756,
+pyelectro >>>     '23:spike_frequency_adaptation': -0.014974747741974222,
+pyelectro >>>     '23:spike_width_adaptation': 0.0067844847504214744,
+pyelectro >>>     '23:trough_decay_exponent': -0.04357925225307838,
+pyelectro >>>     '23:trough_phase_adaptation': -0.006437508651280852}
+Going over acquisition # 24
+pyelectro >>> {   '24:average_last_1percent': -60.48380915323893,
+pyelectro >>>     '24:average_maximum': 50.66572,
+pyelectro >>>     '24:average_minimum': -34.043533,
+pyelectro >>>     '24:first_spike_time': 95.9,
+pyelectro >>>     '24:interspike_time_covar': 0.2757061784222999,
+pyelectro >>>     '24:max_interspike_time': 106.29999999999995,
+pyelectro >>>     '24:max_peak_no': 14,
+pyelectro >>>     '24:maximum': 61.2793,
+pyelectro >>>     '24:mean_spike_frequency': 13.685651121170649,
+pyelectro >>>     '24:min_interspike_time': 42.5,
+pyelectro >>>     '24:min_peak_no': 13,
+pyelectro >>>     '24:minimum': -61.03516,
+pyelectro >>>     '24:peak_decay_exponent': -0.10291055243646331,
+pyelectro >>>     '24:peak_linear_gradient': -0.008156801002617309,
+pyelectro >>>     '24:spike_broadening': 0.647962840377368,
+pyelectro >>>     '24:spike_frequency_adaptation': -0.01033640102347251,
+pyelectro >>>     '24:spike_width_adaptation': 0.0070544336550024695,
+pyelectro >>>     '24:trough_decay_exponent': -0.04136814132208841,
+pyelectro >>>     '24:trough_phase_adaptation': -0.007165702258804302}
+Going over acquisition # 25
+pyelectro >>> {   '25:average_last_1percent': -60.056766510009766,
+pyelectro >>>     '25:average_maximum': 50.34093,
+pyelectro >>>     '25:average_minimum': -33.228947,
+pyelectro >>>     '25:first_spike_time': 95.60000000000001,
+pyelectro >>>     '25:interspike_time_covar': 0.28833246313094774,
+pyelectro >>>     '25:max_interspike_time': 100.80000000000007,
+pyelectro >>>     '25:max_peak_no': 14,
+pyelectro >>>     '25:maximum': 61.40137,
+pyelectro >>>     '25:mean_spike_frequency': 14.023732470334416,
+pyelectro >>>     '25:min_interspike_time': 39.10000000000001,
+pyelectro >>>     '25:min_peak_no': 13,
+pyelectro >>>     '25:minimum': -60.607914,
+pyelectro >>>     '25:peak_decay_exponent': -0.1047695739806843,
+pyelectro >>>     '25:peak_linear_gradient': -0.00879119329941481,
+pyelectro >>>     '25:spike_broadening': 0.6394636967007732,
+pyelectro >>>     '25:spike_frequency_adaptation': -0.011357738090467376,
+pyelectro >>>     '25:spike_width_adaptation': 0.007198805900434394,
+pyelectro >>>     '25:trough_decay_exponent': -0.03898706127522965,
+pyelectro >>>     '25:trough_phase_adaptation': -0.005791081007349543}
+Going over acquisition # 26
+pyelectro >>> {   '26:average_last_1percent': -60.2272580464681,
+pyelectro >>>     '26:average_maximum': 49.776356,
+pyelectro >>>     '26:average_minimum': -32.534084,
+pyelectro >>>     '26:first_spike_time': 94.89999999999999,
+pyelectro >>>     '26:interspike_time_covar': 0.3174070553930572,
+pyelectro >>>     '26:max_interspike_time': 115.70000000000005,
+pyelectro >>>     '26:max_peak_no': 14,
+pyelectro >>>     '26:maximum': 61.15723,
+pyelectro >>>     '26:mean_spike_frequency': 14.697569248162802,
+pyelectro >>>     '26:min_interspike_time': 35.60000000000001,
+pyelectro >>>     '26:min_peak_no': 13,
+pyelectro >>>     '26:minimum': -60.729984,
+pyelectro >>>     '26:peak_decay_exponent': -0.11931629839276492,
+pyelectro >>>     '26:peak_linear_gradient': -0.009603020729143796,
+pyelectro >>>     '26:spike_broadening': 0.6253471365146865,
+pyelectro >>>     '26:spike_frequency_adaptation': -0.015585439927950483,
+pyelectro >>>     '26:spike_width_adaptation': 0.007759081127414656,
+pyelectro >>>     '26:trough_decay_exponent': -0.049101688628808246,
+pyelectro >>>     '26:trough_phase_adaptation': -0.012139424609633551}
+Going over acquisition # 27
+pyelectro >>> {   '27:average_last_1percent': -60.3578732808431,
+pyelectro >>>     '27:average_maximum': 49.30769,
+pyelectro >>>     '27:average_minimum': -32.003548,
+pyelectro >>>     '27:first_spike_time': 93.60000000000001,
+pyelectro >>>     '27:interspike_time_covar': 0.309017296765978,
+pyelectro >>>     '27:max_interspike_time': 109.0,
+pyelectro >>>     '27:max_peak_no': 14,
+pyelectro >>>     '27:maximum': 61.43189,
+pyelectro >>>     '27:mean_spike_frequency': 14.729209154769997,
+pyelectro >>>     '27:min_interspike_time': 32.19999999999999,
+pyelectro >>>     '27:min_peak_no': 13,
+pyelectro >>>     '27:minimum': -60.7605,
+pyelectro >>>     '27:peak_decay_exponent': -0.12538878925370048,
+pyelectro >>>     '27:peak_linear_gradient': -0.009067695791685005,
+pyelectro >>>     '27:spike_broadening': 0.6066765033439258,
+pyelectro >>>     '27:spike_frequency_adaptation': -0.015492078035720953,
+pyelectro >>>     '27:spike_width_adaptation': 0.007539073044770246,
+pyelectro >>>     '27:trough_decay_exponent': -0.05115040330367209,
+pyelectro >>>     '27:trough_phase_adaptation': -0.012545852013557039}
+Going over acquisition # 28
+pyelectro >>> {   '28:average_last_1percent': -60.3798459370931,
+pyelectro >>>     '28:average_maximum': 48.999027,
+pyelectro >>>     '28:average_minimum': -31.055996,
+pyelectro >>>     '28:first_spike_time': 93.4,
+pyelectro >>>     '28:interspike_time_covar': 0.30636145843159784,
+pyelectro >>>     '28:max_interspike_time': 104.70000000000005,
+pyelectro >>>     '28:max_peak_no': 15,
+pyelectro >>>     '28:maximum': 61.2793,
+pyelectro >>>     '28:mean_spike_frequency': 14.760147601476012,
+pyelectro >>>     '28:min_interspike_time': 34.20000000000002,
+pyelectro >>>     '28:min_peak_no': 14,
+pyelectro >>>     '28:minimum': -60.943607,
+pyelectro >>>     '28:peak_decay_exponent': -0.16496940386452533,
+pyelectro >>>     '28:peak_linear_gradient': -0.007631694348641044,
+pyelectro >>>     '28:spike_broadening': 0.5953810644123492,
+pyelectro >>>     '28:spike_frequency_adaptation': -0.014342884276047468,
+pyelectro >>>     '28:spike_width_adaptation': 0.006650416835633624,
+pyelectro >>>     '28:trough_decay_exponent': -0.04668774074305247,
+pyelectro >>>     '28:trough_phase_adaptation': 0.006738292518776989}
+Going over acquisition # 29
+pyelectro >>> {   '29:average_last_1percent': -60.662235260009766,
+pyelectro >>>     '29:average_maximum': 48.664642,
+pyelectro >>>     '29:average_minimum': -30.39551,
+pyelectro >>>     '29:first_spike_time': 93.10000000000001,
+pyelectro >>>     '29:interspike_time_covar': 0.5343365146969321,
+pyelectro >>>     '29:max_interspike_time': 183.60000000000002,
+pyelectro >>>     '29:max_peak_no': 14,
+pyelectro >>>     '29:maximum': 61.370853,
+pyelectro >>>     '29:mean_spike_frequency': 14.458903347792235,
+pyelectro >>>     '29:min_interspike_time': 25.599999999999994,
+pyelectro >>>     '29:min_peak_no': 13,
+pyelectro >>>     '29:minimum': -61.187748,
+pyelectro >>>     '29:peak_decay_exponent': -0.15153571047754788,
+pyelectro >>>     '29:peak_linear_gradient': -0.007862338819211844,
+pyelectro >>>     '29:spike_broadening': 0.5870269764023183,
+pyelectro >>>     '29:spike_frequency_adaptation': -0.016055090374903703,
+pyelectro >>>     '29:spike_width_adaptation': 0.00754720476623759,
+pyelectro >>>     '29:trough_decay_exponent': -0.05167436400749407,
+pyelectro >>>     '29:trough_phase_adaptation': 0.006928896725677521}
+Going over acquisition # 30
+pyelectro >>> {   '30:average_last_1percent': -60.68766657511393,
+pyelectro >>>     '30:average_maximum': 48.13843,
+pyelectro >>>     '30:average_minimum': -29.626032,
+pyelectro >>>     '30:first_spike_time': 92.80000000000001,
+pyelectro >>>     '30:interspike_time_covar': 0.34247923269889735,
+pyelectro >>>     '30:max_interspike_time': 103.89999999999998,
+pyelectro >>>     '30:max_peak_no': 15,
+pyelectro >>>     '30:maximum': 61.767582,
+pyelectro >>>     '30:mean_spike_frequency': 15.688032272523532,
+pyelectro >>>     '30:min_interspike_time': 24.599999999999994,
+pyelectro >>>     '30:min_peak_no': 14,
+pyelectro >>>     '30:minimum': -61.248783,
+pyelectro >>>     '30:peak_decay_exponent': -0.19194537406993217,
+pyelectro >>>     '30:peak_linear_gradient': -0.006994401512067068,
+pyelectro >>>     '30:spike_broadening': 0.5770492253613585,
+pyelectro >>>     '30:spike_frequency_adaptation': -0.01538364588730742,
+pyelectro >>>     '30:spike_width_adaptation': 0.0069293286774622966,
+pyelectro >>>     '30:trough_decay_exponent': -0.04326627973106321,
+pyelectro >>>     '30:trough_phase_adaptation': 0.0064812799362231775}
+Going over acquisition # 31
+pyelectro >>> {   '31:average_last_1percent': -60.63212458292643,
+pyelectro >>>     '31:average_maximum': 48.024498,
+pyelectro >>>     '31:average_minimum': -29.024399,
+pyelectro >>>     '31:first_spike_time': 92.4,
+pyelectro >>>     '31:interspike_time_covar': 0.406847478416553,
+pyelectro >>>     '31:max_interspike_time': 133.5999999999999,
+pyelectro >>>     '31:max_peak_no': 15,
+pyelectro >>>     '31:maximum': 61.889652,
+pyelectro >>>     '31:mean_spike_frequency': 14.704337779644996,
+pyelectro >>>     '31:min_interspike_time': 29.5,
+pyelectro >>>     '31:min_peak_no': 14,
+pyelectro >>>     '31:minimum': -61.30982,
+pyelectro >>>     '31:peak_decay_exponent': -0.1671016453568311,
+pyelectro >>>     '31:peak_linear_gradient': -0.0086990196695813,
+pyelectro >>>     '31:spike_broadening': 0.5569432887124698,
+pyelectro >>>     '31:spike_frequency_adaptation': -0.014767300558908368,
+pyelectro >>>     '31:spike_width_adaptation': 0.006743383637276833,
+pyelectro >>>     '31:trough_decay_exponent': -0.04051025499900451,
+pyelectro >>>     '31:trough_phase_adaptation': 0.006526251236739548}
+Going over acquisition # 32
+pyelectro >>> {   '32:average_last_1percent': -59.76054255167643,
+pyelectro >>>     '32:average_maximum': 47.896324,
+pyelectro >>>     '32:average_minimum': -27.88653,
+pyelectro >>>     '32:first_spike_time': 91.30000000000001,
+pyelectro >>>     '32:interspike_time_covar': 0.34354448310799324,
+pyelectro >>>     '32:max_interspike_time': 106.60000000000002,
+pyelectro >>>     '32:max_peak_no': 15,
+pyelectro >>>     '32:maximum': 62.469486,
+pyelectro >>>     '32:mean_spike_frequency': 15.222355115798628,
+pyelectro >>>     '32:min_interspike_time': 30.700000000000003,
+pyelectro >>>     '32:min_peak_no': 14,
+pyelectro >>>     '32:minimum': -60.42481,
+pyelectro >>>     '32:peak_decay_exponent': -0.2052962133940038,
+pyelectro >>>     '32:peak_linear_gradient': -0.00818069814788547,
+pyelectro >>>     '32:spike_broadening': 0.5505132639070699,
+pyelectro >>>     '32:spike_frequency_adaptation': -0.0127147931736426,
+pyelectro >>>     '32:spike_width_adaptation': 0.006794945084249822,
+pyelectro >>>     '32:trough_decay_exponent': -0.045165955567810896,
+pyelectro >>>     '32:trough_phase_adaptation': 0.00648520248429949}
+Going over acquisition # 33
+pyelectro >>> {   '33:average_last_1percent': -59.76237360636393,
+pyelectro >>>     '33:average_maximum': 47.544212,
+pyelectro >>>     '33:average_minimum': -27.22403,
+pyelectro >>>     '33:first_spike_time': 91.4,
+pyelectro >>>     '33:interspike_time_covar': 0.9530683477414146,
+pyelectro >>>     '33:max_interspike_time': 322.6,
+pyelectro >>>     '33:max_peak_no': 14,
+pyelectro >>>     '33:maximum': 62.28638,
+pyelectro >>>     '33:mean_spike_frequency': 13.151239251390995,
+pyelectro >>>     '33:min_interspike_time': 29.0,
+pyelectro >>>     '33:min_peak_no': 13,
+pyelectro >>>     '33:minimum': -60.42481,
+pyelectro >>>     '33:peak_decay_exponent': -0.21944646857580366,
+pyelectro >>>     '33:peak_linear_gradient': -0.00986060329457358,
+pyelectro >>>     '33:spike_broadening': 0.5524597059029492,
+pyelectro >>>     '33:spike_frequency_adaptation': -0.01666625273183203,
+pyelectro >>>     '33:spike_width_adaptation': 0.006743589954469429,
+pyelectro >>>     '33:trough_decay_exponent': -0.03685620725832345,
+pyelectro >>>     '33:trough_phase_adaptation': -0.012225503917922204}
+
+
+

We now have the following information:

+
    +
  • analysis_results: the results of the analysis by PyElectro; we need these to set the target values for our fitting

  • +
  • currents: the value of stimulation current for each sweep we’ve chosen; we need this for our models

  • +
  • memb_vals: the time series of the membrane potentials and recordings times; we’ll use this to plot the membrane potentials later to compare our fitted model against

  • +
+
+
+

Running the optimisation#

+

To run the optimisation, we want to choose which of the 33 time series we want to fit our model against. +Ideally, we would want to fit our model to all of them. +Here, however, for simplicity and to keep the computation time in check, we only pick two of the 33 sweeps. +(As an exercise, you can change the list to see how that affects your fitting.)

+
    sweeps_to_tune_against = [16,21]
+    report = tune_izh_model(sweeps_to_tune_against, analysis_results, currents)
+
+
+

The Neurotune optimiser uses the evolutionary computation method provided by the Inspyred package. +In short:

+
    +
  • the evolutionary algorithm starts with a population of models, each with a random value for a set of parameters constrained by a max/min value we have supplied

  • +
  • it then calculates a fitness value for each model by comparing the features generated by the model to the target features that we provide

  • +
  • in each generation, it finds the fittest models (parents)

  • +
  • it mutates these to generate the next generation of models (offspring)

  • +
  • it replaces the least fit models with fittest of the new individuals

  • +
+

The idea is that by calculating the fittest parents and offspring, it will find the candidate models that fit the provided target data best. +You can read more about evolutionary computation online (e.g. Wikipedia). +More information on model fitting in computational neuroscience can also be found in the literature. +For example, see this review [PBM04, RGF+11].

+

Here, we follow the following steps:

+
    +
  • we set up a template NeuroML model that will be passed to the optimiser

  • +
  • we list the parameters we want to fit, and provide the extents of their state spaces

  • +
  • we list the target features that the optimiser will use to calculate fitness, and set their weights

  • +
  • finally, we use the run_optimisation function to run the optimisation

  • +
+

The tune_izh_model function shown below is the main workhorse function that does our fitting:

+
def tune_izh_model(acq_list: List, metrics_from_data: Dict, currents: Dict) -> Dict:
+    """Tune networks model against the data.
+
+    Here we generate a network with the necessary number of Izhikevich cells,
+    one for each current stimulus, and tune them against the experimental data.
+
+    :param acq_list: list of indices of acquisitions/sweeps to tune against
+    :type acq_list: list
+    :param metrics_from_data: dictionary with the sweep number as index, and
+        the dictionary containing metrics generated from the analysis
+    :type metrics_from_data: dict
+    :param currents: dictionary with sweep number as index and stimulus current
+        value
+    """
+
+    # length of simulation of the cells---should match the length of the
+    # experiment
+    sim_time = 1500.0
+    # Create a NeuroML template network simulation file that we will use for
+    # the tuning
+    template_doc = NeuroMLDocument(id="IzhTuneNet")
+    # Add an Izhikevich cell with some parameters to the document
+    template_doc.izhikevich2007_cells.append(
+        Izhikevich2007Cell(
+            id="Izh2007",
+            C="100pF",
+            v0="-60mV",
+            k="0.7nS_per_mV",
+            vr="-60mV",
+            vt="-40mV",
+            vpeak="35mV",
+            a="0.03per_ms",
+            b="-2nS",
+            c="-50.0mV",
+            d="100pA",
+        )
+    )
+    template_doc.networks.append(Network(id="Network0"))
+    # Add a cell for each acquisition list
+    popsize = len(acq_list)
+    template_doc.networks[0].populations.append(
+        Population(id="Pop0", component="Izh2007", size=popsize)
+    )
+
+    # Add a current source for each cell, matching the currents that
+    # were used in the experimental study.
+    counter = 0
+    for acq in acq_list:
+        template_doc.pulse_generators.append(
+            PulseGenerator(
+                id="Stim{}".format(counter),
+                delay="80ms",
+                duration="1000ms",
+                amplitude="{}pA".format(currents[acq]),
+            )
+        )
+        template_doc.networks[0].explicit_inputs.append(
+            ExplicitInput(
+                target="Pop0[{}]".format(counter), input="Stim{}".format(counter)
+            )
+        )
+        counter = counter + 1
+
+    # Print a summary
+    print(template_doc.summary())
+
+    # Write to a neuroml file and validate it.
+    reference = "TuneIzhFergusonPyr3"
+    template_filename = "{}.net.nml".format(reference)
+    write_neuroml2_file(template_doc, template_filename, validate=True)
+
+    # Now for the tuning bits
+
+    # format is type:id/variable:id/units
+    # supported types: cell/channel/izhikevich2007cell
+    # supported variables:
+    #  - channel: vShift
+    #  - cell: channelDensity, vShift_channelDensity, channelDensityNernst,
+    #  erev_id, erev_ion, specificCapacitance, resistivity
+    #  - izhikevich2007Cell: all available attributes
+
+    # we want to tune these parameters within these ranges
+    # param: (min, max)
+    parameters = {
+        "izhikevich2007Cell:Izh2007/C/pF": (100, 300),
+        "izhikevich2007Cell:Izh2007/k/nS_per_mV": (0.01, 2),
+        "izhikevich2007Cell:Izh2007/vr/mV": (-70, -50),
+        "izhikevich2007Cell:Izh2007/vt/mV": (-60, 0),
+        "izhikevich2007Cell:Izh2007/vpeak/mV": (35, 70),
+        "izhikevich2007Cell:Izh2007/a/per_ms": (0.001, 0.4),
+        "izhikevich2007Cell:Izh2007/b/nS": (-10, 10),
+        "izhikevich2007Cell:Izh2007/c/mV": (-65, -10),
+        "izhikevich2007Cell:Izh2007/d/pA": (50, 500),
+    }  # type: Dict[str, Tuple[float, float]]
+
+    # Set up our target data and so on
+    ctr = 0
+    target_data = {}
+    weights = {}
+    for acq in acq_list:
+        # data to fit to:
+        # format: path/to/variable:metric
+        # metric from pyelectro, for example:
+        # https://pyelectro.readthedocs.io/en/latest/pyelectro.html?highlight=mean_spike_frequency#pyelectro.analysis.mean_spike_frequency
+        mean_spike_frequency = "Pop0[{}]/v:mean_spike_frequency".format(ctr)
+        average_last_1percent = "Pop0[{}]/v:average_last_1percent".format(ctr)
+        first_spike_time = "Pop0[{}]/v:first_spike_time".format(ctr)
+
+        # each metric can have an associated weight
+        weights[mean_spike_frequency] = 1
+        weights[average_last_1percent] = 1
+        weights[first_spike_time] = 1
+
+        # value of the target data from our data set
+        target_data[mean_spike_frequency] = metrics_from_data[acq][
+            "{}:mean_spike_frequency".format(acq)
+        ]
+        target_data[average_last_1percent] = metrics_from_data[acq][
+            "{}:average_last_1percent".format(acq)
+        ]
+        target_data[first_spike_time] = metrics_from_data[acq][
+            "{}:first_spike_time".format(acq)
+        ]
+
+        # only add these if the experimental data includes them
+        # these are only generated for traces with spikes
+        if "{}:average_maximum".format(acq) in metrics_from_data[acq]:
+            average_maximum = "Pop0[{}]/v:average_maximum".format(ctr)
+            weights[average_maximum] = 1
+            target_data[average_maximum] = metrics_from_data[acq][
+                "{}:average_maximum".format(acq)
+            ]
+        if "{}:average_minimum".format(acq) in metrics_from_data[acq]:
+            average_minimum = "Pop0[{}]/v:average_minimum".format(ctr)
+            weights[average_minimum] = 1
+            target_data[average_minimum] = metrics_from_data[acq][
+                "{}:average_minimum".format(acq)
+            ]
+
+        ctr = ctr + 1
+
+    # simulator to use
+    simulator = "jNeuroML"
+
+    return run_optimisation(
+        # Prefix for new files
+        prefix="TuneIzh",
+        # Name of the NeuroML template file
+        neuroml_file=template_filename,
+        # Name of the network
+        target="Network0",
+        # Parameters to be fitted
+        parameters=list(parameters.keys()),
+        # Our max and min constraints
+        min_constraints=[v[0] for v in parameters.values()],
+        max_constraints=[v[1] for v in parameters.values()],
+        # Weights we set for parameters
+        weights=weights,
+        # The experimental metrics to fit to
+        target_data=target_data,
+        # Simulation time
+        sim_time=sim_time,
+        # EC parameters
+        population_size=100,
+        max_evaluations=500,
+        num_selected=30,
+        num_offspring=50,
+        mutation_rate=0.9,
+        num_elites=3,
+        # Seed value
+        seed=12345,
+        # Simulator
+        simulator=simulator,
+        dt=0.025,
+        show_plot_already='-nogui' not in sys.argv,
+        save_to_file="fitted_izhikevich_fitness.png",
+        save_to_file_scatter="fitted_izhikevich_scatter.png",
+        save_to_file_hist="fitted_izhikevich_hist.png",
+        save_to_file_output="fitted_izhikevich_output.png",
+        num_parallel_evaluations=4,
+    )
+
+
+

Let us walk through the different sections of this function.

+
+

Writing a template model#

+

In this example, we want to fit the parameters of an Izhikevich cell to our data such that simulating the cell then gives us membrane potentials similar to those observed in the experiment. +Following the Izhikevich network example, we set up a template network with one Izhikevich cell for each experimental recording that we want to fit. +For each of these cells, we provide a current stimulus matching the current used in the current clamp experiments that we obtained our recordings from:

+
    # length of simulation of the cells---should match the length of the
+    # experiment
+    sim_time = 1500.0
+    # Create a NeuroML template network simulation file that we will use for
+    # the tuning
+    template_doc = NeuroMLDocument(id="IzhTuneNet")
+    # Add an Izhikevich cell with some parameters to the document
+    template_doc.izhikevich2007_cells.append(
+        Izhikevich2007Cell(
+            id="Izh2007",
+            C="100pF",
+            v0="-60mV",
+            k="0.7nS_per_mV",
+            vr="-60mV",
+            vt="-40mV",
+            vpeak="35mV",
+            a="0.03per_ms",
+            b="-2nS",
+            c="-50.0mV",
+            d="100pA",
+        )
+    )
+    template_doc.networks.append(Network(id="Network0"))
+    # Add a cell for each acquisition list
+    popsize = len(acq_list)
+    template_doc.networks[0].populations.append(
+        Population(id="Pop0", component="Izh2007", size=popsize)
+    )
+
+    # Add a current source for each cell, matching the currents that
+    # were used in the experimental study.
+    counter = 0
+    for acq in acq_list:
+        template_doc.pulse_generators.append(
+            PulseGenerator(
+                id="Stim{}".format(counter),
+                delay="80ms",
+                duration="1000ms",
+                amplitude="{}pA".format(currents[acq]),
+            )
+        )
+        template_doc.networks[0].explicit_inputs.append(
+            ExplicitInput(
+                target="Pop0[{}]".format(counter), input="Stim{}".format(counter)
+            )
+        )
+        counter = counter + 1
+
+    # Print a summary
+    print(template_doc.summary())
+
+    # Write to a neuroml file and validate it.
+    reference = "TuneIzhFergusonPyr3"
+    template_filename = "{}.net.nml".format(reference)
+    write_neuroml2_file(template_doc, template_filename, validate=True)
+
+
+

The resultant network template model for our two chosen recordings is shown below:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="IzhTuneNet">
+    <izhikevich2007Cell id="Izh2007" C="100pF" v0="-60mV" k="0.7nS_per_mV" vr="-60mV" vt="-40mV" vpeak="35mV" a="0.03per_ms" b="-2nS" c="-50.0mV" d="100pA"/>
+    <pulseGenerator id="Stim0" delay="80ms" duration="1000ms" amplitude="152.0pA"/>
+    <pulseGenerator id="Stim1" delay="80ms" duration="1000ms" amplitude="202.0pA"/>
+    <network id="Network0">
+        <population id="Pop0" component="Izh2007" size="2"/>
+        <explicitInput target="Pop0[0]" input="Stim0"/>
+        <explicitInput target="Pop0[1]" input="Stim1"/>
+    </network>
+</neuroml>
+
+
+

Please note that the initial parameters of the Izhikevich Cell do not matter here because the optimiser will modify these to run the candidate simulations.

+
+
+

Setting up the optimisation parameters#

+

The next step is to set the features/metrics that we want to fit:

+

The parameters dictionary contains the specifications of the parameters that we wish to fit, along with their minimum and maximum permitted values.

+
    # we want to tune these parameters within these ranges
+    # param: (min, max)
+    parameters = {
+        "izhikevich2007Cell:Izh2007/C/pF": (100, 300),
+        "izhikevich2007Cell:Izh2007/k/nS_per_mV": (0.01, 2),
+        "izhikevich2007Cell:Izh2007/vr/mV": (-70, -50),
+        "izhikevich2007Cell:Izh2007/vt/mV": (-60, 0),
+        "izhikevich2007Cell:Izh2007/vpeak/mV": (35, 70),
+        "izhikevich2007Cell:Izh2007/a/per_ms": (0.001, 0.4),
+        "izhikevich2007Cell:Izh2007/b/nS": (-10, 10),
+        "izhikevich2007Cell:Izh2007/c/mV": (-65, -10),
+        "izhikevich2007Cell:Izh2007/d/pA": (50, 500),
+    }  # type: Dict[str, Tuple[float, float]]
+
+
+

The format of the parameter specification is: ComponentType:ComponentID/VariableName[:VariableID]/Units. +So, for example, to fit the Capacitance of the Izhikevich cell, our parameter specification string is: izhikevich2007Cell:Izh2007/C/pF.

+

All NeuroML Cell and Channel ComponentTypes can be fitted using the NeuroMLTuner.

+

Next, we specify the target data that we want to fit against.

+
    # Set up our target data and so on
+    ctr = 0
+    target_data = {}
+    weights = {}
+    for acq in acq_list:
+        # data to fit to:
+        # format: path/to/variable:metric
+        # metric from pyelectro, for example:
+        # https://pyelectro.readthedocs.io/en/latest/pyelectro.html?highlight=mean_spike_frequency#pyelectro.analysis.mean_spike_frequency
+        mean_spike_frequency = "Pop0[{}]/v:mean_spike_frequency".format(ctr)
+        average_last_1percent = "Pop0[{}]/v:average_last_1percent".format(ctr)
+        first_spike_time = "Pop0[{}]/v:first_spike_time".format(ctr)
+
+        # each metric can have an associated weight
+        weights[mean_spike_frequency] = 1
+        weights[average_last_1percent] = 1
+        weights[first_spike_time] = 1
+
+        # value of the target data from our data set
+        target_data[mean_spike_frequency] = metrics_from_data[acq][
+            "{}:mean_spike_frequency".format(acq)
+        ]
+        target_data[average_last_1percent] = metrics_from_data[acq][
+            "{}:average_last_1percent".format(acq)
+        ]
+        target_data[first_spike_time] = metrics_from_data[acq][
+            "{}:first_spike_time".format(acq)
+        ]
+
+        # only add these if the experimental data includes them
+        # these are only generated for traces with spikes
+        if "{}:average_maximum".format(acq) in metrics_from_data[acq]:
+            average_maximum = "Pop0[{}]/v:average_maximum".format(ctr)
+            weights[average_maximum] = 1
+            target_data[average_maximum] = metrics_from_data[acq][
+                "{}:average_maximum".format(acq)
+            ]
+        if "{}:average_minimum".format(acq) in metrics_from_data[acq]:
+            average_minimum = "Pop0[{}]/v:average_minimum".format(ctr)
+            weights[average_minimum] = 1
+            target_data[average_minimum] = metrics_from_data[acq][
+                "{}:average_minimum".format(acq)
+            ]
+
+        ctr = ctr + 1
+
+
+

As we have set up a cell for each recording that we want to fit to, we must also set the target value for each cell. +We pick four features from a subset of features that PyElectro provided us with:

+
    +
  • mean_spike_frequency

  • +
  • average_last_1percent

  • +
  • average_maximum

  • +
  • average_minimum

  • +
+

The last two can only be calculated for membrane potential data that includes spikes. +Since a few of the experimental recordings to not show any spikes, these two metrics will not be calculated for them. +So, we only add them for the corresponding cell only if they are present in the features for the chosen recording.

+

The format for the target_data is similar to that of the parameters. +The keys of the target_data dictionary are the specifications for the metrics. +The format for these is: path/to/variable:pyelectro metric. +You can learn more about constructing paths in NeuroML here. +The value for the each key is the corresponding metric that was calculated for us by PyElectro (in analysis_results). +The for loop will set the target_data to this (printed by pyNeuroML when we run the script):

+
target_data =  {
+  'Pop0[0]/v:mean_spike_frequency': 7.033585370142431,
+  'Pop0[0]/v:average_last_1percent': -60.84635798136393,
+  'Pop0[0]/v:average_maximum': 58.73414,
+  'Pop0[0]/v:average_minimum': -43.800358,
+  'Pop0[1]/v:mean_spike_frequency': 10.8837614279495,
+  'Pop0[1]/v:average_last_1percent': -60.380863189697266,
+  'Pop0[1]/v:average_maximum': 54.52382,
+  'Pop0[1]/v:average_minimum': -39.78882
+}
+
+
+

Similarly, we also set up the weights for each target metric in the weights variable:

+
weights = {
+ 'Pop0[0]/v:mean_spike_frequency': 1,
+ 'Pop0[0]/v:average_last_1percent': 1,
+ 'Pop0[0]/v: average_maximum': 1,
+ 'Pop0[0]/v:average_minimum': 1,
+ 'Pop0[1]/v:mean_spike_frequency': 1,
+ 'Pop0[1]/v:average_last_1percent': 1,
+ 'Pop0[1]/v:average_maximum': 1,
+ 'Pop0[1]/v:average_minimum': 1
+ }
+
+
+

For simplicity, we set the weights for all as 1 here.

+
+
+

Calling the optimisation function#

+

The last step is to call our run_optimisation function with the various parameters that we have set up. +Here, for simplicity, we use the jNeuroML simulator. +For multi-compartmental models, however, we will need to use the jNeuroML_NEURON simulator (since jNeuroML only supports single compartment simulations). +A number of arguments to the function are specific to evolutionary computation, and their discussion is beyond the scope of this tutorial.

+
    # simulator to use
+    simulator = "jNeuroML"
+
+    return run_optimisation(
+        # Prefix for new files
+        prefix="TuneIzh",
+        # Name of the NeuroML template file
+        neuroml_file=template_filename,
+        # Name of the network
+        target="Network0",
+        # Parameters to be fitted
+        parameters=list(parameters.keys()),
+        # Our max and min constraints
+        min_constraints=[v[0] for v in parameters.values()],
+        max_constraints=[v[1] for v in parameters.values()],
+        # Weights we set for parameters
+        weights=weights,
+        # The experimental metrics to fit to
+        target_data=target_data,
+        # Simulation time
+        sim_time=sim_time,
+        # EC parameters
+        population_size=100,
+        max_evaluations=500,
+        num_selected=30,
+        num_offspring=50,
+        mutation_rate=0.9,
+        num_elites=3,
+        # Seed value
+        seed=12345,
+        # Simulator
+        simulator=simulator,
+        dt=0.025,
+        show_plot_already='-nogui' not in sys.argv,
+        save_to_file="fitted_izhikevich_fitness.png",
+        save_to_file_scatter="fitted_izhikevich_scatter.png",
+        save_to_file_hist="fitted_izhikevich_hist.png",
+        save_to_file_output="fitted_izhikevich_output.png",
+        num_parallel_evaluations=4,
+    )
+
+
+

The run_optimisation function will print out the optimisation report, and also return it so that it can be stored in a variable for further use. +The terminal output is shown below:

+
Ran 500 evaluations (pop: 100) in 582.205449 seconds (9.703424 mins total; 1.164411s per eval)
+
+---------- Best candidate ------------------------------------------
+{   'Pop0[0]/v:average_last_1percent': -59.276969863333285,
+    'Pop0[0]/v:average_maximum': 47.35760225,
+    'Pop0[0]/v:average_minimum': -53.95061271428572,
+    'Pop0[0]/v:first_spike_time': 170.1,
+    'Pop0[0]/v:interspike_time_covar': 0.1330373936860586,
+    'Pop0[0]/v:max_interspike_time': 190.57499999999982,
+    'Pop0[0]/v:max_peak_no': 8,
+    'Pop0[0]/v:maximum': 47.427714,
+    'Pop0[0]/v:mean_spike_frequency': 6.957040276293886,
+    'Pop0[0]/v:min_interspike_time': 135.25000000000003,
+    'Pop0[0]/v:min_peak_no': 7,
+    'Pop0[0]/v:minimum': -68.13577,
+    'Pop0[0]/v:peak_decay_exponent': 0.0003379360943630205,
+    'Pop0[0]/v:peak_linear_gradient': -3.270149536895308e-05,
+    'Pop0[0]/v:spike_broadening': 0.982357731987536,
+    'Pop0[0]/v:spike_frequency_adaptation': -0.016935379943933133,
+    'Pop0[0]/v:spike_width_adaptation': 0.011971808793771004,
+    'Pop0[0]/v:trough_decay_exponent': -0.0008421760726029059,
+    'Pop0[0]/v:trough_phase_adaptation': -0.014231837120099502,
+    'Pop0[1]/v:average_last_1percent': -59.28251401166662,
+    'Pop0[1]/v:average_maximum': 47.242452454545464,
+    'Pop0[1]/v:average_minimum': -48.287914,
+    'Pop0[1]/v:first_spike_time': 146.7,
+    'Pop0[1]/v:interspike_time_covar': 0.01075626702836981,
+    'Pop0[1]/v:max_interspike_time': 91.67499999999998,
+    'Pop0[1]/v:max_peak_no': 11,
+    'Pop0[1]/v:maximum': 47.423363,
+    'Pop0[1]/v:mean_spike_frequency': 10.973033769511423,
+    'Pop0[1]/v:min_interspike_time': 88.20000000000002,
+    'Pop0[1]/v:min_peak_no': 10,
+    'Pop0[1]/v:minimum': -62.58064000000001,
+    'Pop0[1]/v:peak_decay_exponent': 0.0008036004162568405,
+    'Pop0[1]/v:peak_linear_gradient': -0.00012436953066659044,
+    'Pop0[1]/v:spike_broadening': 0.9877761288704633,
+    'Pop0[1]/v:spike_frequency_adaptation': 0.0064956079899488595,
+    'Pop0[1]/v:spike_width_adaptation': 0.008982392557695507,
+    'Pop0[1]/v:trough_decay_exponent': -0.004658690933014975,
+    'Pop0[1]/v:trough_phase_adaptation': 0.009514671770845617}
+
+TARGETS:
+{   'Pop0[0]/v:average_last_1percent': -60.84635798136393,
+    'Pop0[0]/v:average_maximum': 58.73414,
+    'Pop0[0]/v:average_minimum': -43.800358,
+    'Pop0[0]/v:mean_spike_frequency': 7.033585370142431,
+    'Pop0[1]/v:average_last_1percent': -60.380863189697266,
+    'Pop0[1]/v:average_maximum': 54.52382,
+    'Pop0[1]/v:average_minimum': -39.78882,
+    'Pop0[1]/v:mean_spike_frequency': 10.8837614279495}
+
+TUNED VALUES:
+{   'Pop0[0]/v:average_last_1percent': -59.276969863333285,
+    'Pop0[0]/v:average_maximum': 47.35760225,
+    'Pop0[0]/v:average_minimum': -53.95061271428572,
+    'Pop0[0]/v:mean_spike_frequency': 6.957040276293886,
+    'Pop0[1]/v:average_last_1percent': -59.28251401166662,
+    'Pop0[1]/v:average_maximum': 47.242452454545464,
+    'Pop0[1]/v:average_minimum': -48.287914,
+    'Pop0[1]/v:mean_spike_frequency': 10.973033769511423}
+
+FITNESS: 0.003633
+
+FITTEST: {   'izhikevich2007Cell:Izh2007/C/pF': 240.6982897890555,
+    'izhikevich2007Cell:Izh2007/a/per_ms': 0.03863507615280202,
+    'izhikevich2007Cell:Izh2007/b/nS': 2.0112449831346746,
+    'izhikevich2007Cell:Izh2007/c/mV': -43.069939785498356,
+    'izhikevich2007Cell:Izh2007/d/pA': 212.50982499591083,
+    'izhikevich2007Cell:Izh2007/k/nS_per_mV': 0.24113869560362797,
+    'izhikevich2007Cell:Izh2007/vpeak/mV': 47.44063356996336,
+    'izhikevich2007Cell:Izh2007/vr/mV': -59.283747806929135,
+    'izhikevich2007Cell:Izh2007/vt/mV': -48.9131459978619}
+
+
+

It will also generate a number of plots (shown below):

+
    +
  • showing the evolution of the parameters being fitted, with indications of the fitness value: larger circles mean more fitness

  • +
  • the change in the overall fitness value as the population evolves

  • +
  • distributions of the values of the parameters being fitted, with indications of the fitness value: darker lines mean higher fitness

  • +
+
+Evolution of parameters. +
+

Fig. 48 The figure shows the values of various parameters throughout the evolution, with larger circles having higher values of fitness.#

+
+
+
+Evolution of fitness. +
+

Fig. 49 The figure shows the trend of the fitness throughout the evolution.#

+
+
+
+Histograms of values of fitting parameters. +
+

Fig. 50 The figure shows the distribution of values that for each parameter throughout the evolution. Darker lines have higher fitness values.#

+
+
+
+
+
+

Viewing results#

+

The tuner also generates a plot with the membrane potential of a cell using the fitted parameter values (shown on the top of the page). +Here, to document how the fitted parameters are to be extracted from the output of the run_optimisation function, we also construct a model to use the fitted parameters ourselves and plot the membrane potential to compare it against the experimental data.

+
+

Extracting results and running a fitted model#

+

This is done in the run_fitted_cell_simulation function:

+
def run_fitted_cell_simulation(
+    sweeps_to_tune_against: List, tuning_report: Dict, simulation_id: str
+) -> None:
+    """Run a simulation with the values obtained from the fitting
+
+    :param tuning_report: tuning report from the optimser
+    :type tuning_report: Dict
+    :param simulation_id: text id of simulation
+    :type simulation_id: str
+
+    """
+    # get the fittest variables
+    fittest_vars = tuning_report["fittest vars"]
+    C = str(fittest_vars["izhikevich2007Cell:Izh2007/C/pF"]) + "pF"
+    k = str(fittest_vars["izhikevich2007Cell:Izh2007/k/nS_per_mV"]) + "nS_per_mV"
+    vr = str(fittest_vars["izhikevich2007Cell:Izh2007/vr/mV"]) + "mV"
+    vt = str(fittest_vars["izhikevich2007Cell:Izh2007/vt/mV"]) + "mV"
+    vpeak = str(fittest_vars["izhikevich2007Cell:Izh2007/vpeak/mV"]) + "mV"
+    a = str(fittest_vars["izhikevich2007Cell:Izh2007/a/per_ms"]) + "per_ms"
+    b = str(fittest_vars["izhikevich2007Cell:Izh2007/b/nS"]) + "nS"
+    c = str(fittest_vars["izhikevich2007Cell:Izh2007/c/mV"]) + "mV"
+    d = str(fittest_vars["izhikevich2007Cell:Izh2007/d/pA"]) + "pA"
+
+    # Create a simulation using our obtained parameters.
+    # Note that the tuner generates a graph with the fitted values already, but
+    # we want to keep a copy of our fitted cell also, so we'll create a NeuroML
+    # Document ourselves also.
+    sim_time = 1500.0
+    simulation_doc = NeuroMLDocument(id="FittedNet")
+    # Add an Izhikevich cell with some parameters to the document
+    simulation_doc.izhikevich2007_cells.append(
+        Izhikevich2007Cell(
+            id="Izh2007",
+            C=C,
+            v0="-60mV",
+            k=k,
+            vr=vr,
+            vt=vt,
+            vpeak=vpeak,
+            a=a,
+            b=b,
+            c=c,
+            d=d,
+        )
+    )
+    simulation_doc.networks.append(Network(id="Network0"))
+    # Add a cell for each acquisition list
+    popsize = len(sweeps_to_tune_against)
+    simulation_doc.networks[0].populations.append(
+        Population(id="Pop0", component="Izh2007", size=popsize)
+    )
+
+    # Add a current source for each cell, matching the currents that
+    # were used in the experimental study.
+    counter = 0
+    for acq in sweeps_to_tune_against:
+        simulation_doc.pulse_generators.append(
+            PulseGenerator(
+                id="Stim{}".format(counter),
+                delay="80ms",
+                duration="1000ms",
+                amplitude="{}pA".format(currents[acq]),
+            )
+        )
+        simulation_doc.networks[0].explicit_inputs.append(
+            ExplicitInput(
+                target="Pop0[{}]".format(counter), input="Stim{}".format(counter)
+            )
+        )
+        counter = counter + 1
+
+    # Print a summary
+    print(simulation_doc.summary())
+
+    # Write to a neuroml file and validate it.
+    reference = "FittedIzhFergusonPyr3"
+    simulation_filename = "{}.net.nml".format(reference)
+    write_neuroml2_file(simulation_doc, simulation_filename, validate=True)
+
+    simulation = LEMSSimulation(
+        sim_id=simulation_id,
+        duration=sim_time,
+        dt=0.1,
+        target="Network0",
+        simulation_seed=54321,
+    )
+    simulation.include_neuroml2_file(simulation_filename)
+    simulation.create_output_file("output0", "{}.v.dat".format(simulation_id))
+    counter = 0
+    for acq in sweeps_to_tune_against:
+        simulation.add_column_to_output_file(
+            "output0", "Pop0[{}]".format(counter), "Pop0[{}]/v".format(counter)
+        )
+        counter = counter + 1
+    simulation_file = simulation.save_to_file()
+    # simulate
+    run_lems_with_jneuroml(simulation_file, max_memory="2G", nogui=True, plot=False)
+
+
+
+

First, we extract the fitted parameters from the dictionary returned by the run_optimisation function. +Then, we use these parameters to set up a simple NeuroML network and run a test simulation, recording the values of membrane potentials generated by the cells. +Please note that the current stimulus to the cells in this test model must also match the values that were used in the experiment, and so also in the fitting.

+
+
+

Plotting model generated and experimentally recorded membrane potentials#

+

Finally, in the plot_sim_data function, we plot the membrane potentials from our fitted cells and the experimental data to see visually inspect the results of our fitting:

+
def plot_sim_data(
+    sweeps_to_tune_against: List, simulation_id: str, memb_pots: Dict
+) -> None:
+    """Plot data from our fitted simulation
+
+    :param simulation_id: string id of simulation
+    :type simulation_id: str
+    """
+    # Plot
+    data_array = np.loadtxt("%s.v.dat" % simulation_id)
+
+    # construct data for plotting
+    counter = 0
+    time_vals_list = []
+    sim_v_list = []
+    data_v_list = []
+    data_t_list = []
+    stim_vals = []
+    for acq in sweeps_to_tune_against:
+        stim_vals.append("{}pA".format(currents[acq]))
+
+        # remains the same for all columns
+        time_vals_list.append(data_array[:, 0] * 1000.0)
+        sim_v_list.append(data_array[:, counter + 1] * 1000.0)
+
+        data_v_list.append(memb_pots[acq][1])
+        data_t_list.append(memb_pots[acq][0])
+
+        counter = counter + 1
+
+    # Model membrane potential plot
+    generate_plot(
+        xvalues=time_vals_list,
+        yvalues=sim_v_list,
+        labels=stim_vals,
+        title="Membrane potential (model)",
+        show_plot_already=False,
+        save_figure_to="%s-model-v.png" % simulation_id,
+        xaxis="time (ms)",
+        yaxis="membrane potential (mV)",
+    )
+    # data membrane potential plot
+    generate_plot(
+        xvalues=data_t_list,
+        yvalues=data_v_list,
+        labels=stim_vals,
+        title="Membrane potential (exp)",
+        show_plot_already=False,
+        save_figure_to="%s-exp-v.png" % simulation_id,
+        xaxis="time (ms)",
+        yaxis="membrane potential (mV)",
+    )
+
+
+
+
+

This generates the following figures:

+
+
+
+
+
+Membrane potential from example experimental data. +
+

Fig. 51 Membrane potential from the experimental data.#

+
+
+
+
+
+
+
+Membrane potential obtained from example fitted model. +
+

Fig. 52 Membrane potential obtained from the model with highest fitness.#

+
+
+
+
+
+
+

We can clearly see the similarity between our fitted model and the experimental data. +A number of tweaks can be made to improve the fitting. +For example, pyNeuroML also provides a two staged optimisation function: run_2stage_optimisation that allows users to optimise sets of parameters in two different stages. +The graphs also show ranges of parameters that provide fits, so users can also hand-tune their models further as required.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Paths.html b/Userdocs/Paths.html new file mode 100644 index 00000000..3bb35eef --- /dev/null +++ b/Userdocs/Paths.html @@ -0,0 +1,870 @@ + + + + + + + + + + + Paths — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Paths

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Paths#

+

Since NeuroMLv2 and LEMS are both XML based, entities in models and simulations must be referred to using paths (XPath like). +This page documents how paths can be constructed, and how they can be used to refer to entities in NeuroML/LEMS based models and simulations (e.g. in a LEMS Simulation file).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

operator

description

function

example

/

forward slash

used to split the levels in a path string

see below

.

single period

refers to the level of the current node (usually omitted)

see below

..

two periods

refers to the level of the current node’s parent node

see below

[x]

square brackets

used to refer to a particular instance (in this case, x) in Components/Elements that have a size attribute (like population)

see below

:

colon

used to refer to a particular Component instance for attachments

ex

+

Paths start from any element and ascend/descend to refer to the entity that is to be referenced.

+
+

Example#

+

For example, in the following block of code, based on the Izhikevich network example, a network is defined in NeuroML with 2 populations:

+
    <network id="IzNet">
+        <population id="IzPop0" component="iz2007RS0" size="5">
+            <property tag="color" value="0 0 .8"/>
+        </population>
+        <populationList id="IzPop1" component="iz2007RS0">
+            <property tag="color" value=".8 0 0"/>
+            <instance id=0>
+                <location x="0" y="0" z="0" />
+            </instance>
+            <instance id=1>
+                <location x="1" y="0" z="0" />
+            </instance>
+            <instance id=2>
+                <location x="2" y="0" z="0" />
+            </instance>
+            <instance id=3>
+                <location x="3" y="0" z="0" />
+            </instance>
+            <instance id=4>
+                <location x="4" y="0" z="0" />
+            </instance>
+        </populationList>
+        <projection id="proj" presynapticPopulation="IzPop0" postsynapticPopulation="IzPop1" synapse="syn0">
+            <connection id="0" preCellId="../IzPop0[0]" postCellId="../IzPop1/0"/>
+            <connection id="1" preCellId="../IzPop0[0]" postCellId="../IzPop1/1"/>
+            <connection id="2" preCellId="../IzPop0[0]" postCellId="../IzPop1/2"/>
+            ...
+        </projection>
+        <explicitInput target="IzPop0[0]" input="pg_0"/>
+        <explicitInput target="IzPop0[1]" input="pg_1"/>
+        <explicitInput target="IzPop0[2]" input="pg_2"/>
+        <explicitInput target="IzPop0[3]" input="pg_3"/>
+        <explicitInput target="IzPop0[4]" input="pg_4"/>
+    </network>
+</neuroml>
+
+
+

Here, in the explicitInput node, we need to refer to neurons of the IzPop0 population node. +Since explicitInput and population are siblings (both have the IzNet network as parent), they are at the same level. +Therefore, in explicitInput, one can refer directly to IzPop0.

+

The projection and population nodes are also siblings and therefore are at the same level. +So, in the projection tag also, we can refer to the population nodes directly. +The connection nodes, however, are children of the projection node. +Therefore, for the connection nodes, the population nodes are at the parent level, and we must use ../IzPop0 to refer to them.

+

../IzPop0 means “go up one level to the parent level (to projection) and then refer to IzPop0”. +../ can be used as many times as required and wherever required in the path. +For example, ../../../ would mean “go up three levels”.

+
+
+

Helper functions in pyNeuroML#

+
+

Note

+

These functions require pyNeuroML version 0.5.18+, and pylems version 0.5.8+.

+
+

From version 0.5.18, pyNeuroML includes the list_recording_paths_for_exposures helper function that can list the exposures and their recordable paths from a NeuroML 2 model:

+
>>> import pyneuroml.pynml
+>>> help(pynml.list_recording_paths_for_exposures)
+
+Help on function list_recording_paths_for_exposures in module pyneuroml.pynml:
+
+list_recording_paths_for_exposures(nml_doc_fn, substring='', target='')
+    List the recording path strings for exposures.
+
+    This wraps around `lems.model.list_recording_paths` to list the recording
+    paths in the given NeuroML2 model. The only difference between the two is
+    that the `lems.model.list_recording_paths` function is not aware of the
+    NeuroML2 component types (since it's for any LEMS models in general), but
+    this one is.
+
+
+

It can be run on the example Izhikevich network example:

+
>>> pynml.list_recording_paths_for_exposures("izhikevich2007_network.nml", substring="", target="IzNet")
+['IzNet/IzPop0[0]/iMemb',
+ 'IzNet/IzPop0[0]/iSyn',
+ 'IzNet/IzPop0[0]/u',
+ 'IzNet/IzPop0[0]/v',
+ 'IzNet/IzPop0[1]/iMemb',
+ 'IzNet/IzPop0[1]/iSyn',
+ 'IzNet/IzPop0[1]/u',
+ 'IzNet/IzPop0[1]/v',
+ 'IzNet/IzPop0[2]/iMemb',
+ 'IzNet/IzPop0[2]/iSyn',
+ 'IzNet/IzPop0[2]/u',
+ 'IzNet/IzPop0[2]/v',
+ 'IzNet/IzPop0[3]/iMemb',
+ 'IzNet/IzPop0[3]/iSyn',
+ 'IzNet/IzPop0[3]/u',
+ 'IzNet/IzPop0[3]/v',
+ 'IzNet/IzPop0[4]/iMemb',
+ 'IzNet/IzPop0[4]/iSyn',
+ 'IzNet/IzPop0[4]/u',
+ 'IzNet/IzPop0[4]/v',
+ 'IzNet/IzPop1[0]/iMemb',
+..
+]
+
+
+

Note that this function parsers the model description only, not the built simulation description. +Therefore, it will not necessarily list the complete list of paths. +Also worth noting is that since it parses and iterates over the expanded representation of the model, it can be slow and return long lists of results on larger models. +It is therefore, best to use this with the substring option to narrow its scope.

+

An associated helper function list_exposures is also available:

+
>>> import pyneuroml.pynml
+>>> help(pynml.list_exposures)
+
+list_exposures(nml_doc_fn, substring='')
+    List exposures in a NeuroML model document file.
+
+    This wraps around `lems.model.list_exposures` to list the exposures in a
+    NeuroML2 model. The only difference between the two is that the
+    `lems.model.list_exposures` function is not aware of the NeuroML2 component
+    types (since it's for any LEMS models in general), but this one is.
+
+    The returned dictionary is of the form:
+
+    ..
+        {
+            "component": ["exp1", "exp2"]
+        }
+
+
+

When run on the example Izhikevich network example, it will return:

+
>>> pynml.list_exposures("izhikevich2007_network.nml")
+
+{<lems.model.component.FatComponent at 0x7f25b62caca0>: {'g': <lems.model.component.Exposure at 0x7f25dd1d2be0>,
+  'i': <lems.model.component.Exposure at 0x7f25dc921e80>},
+ <lems.model.component.FatComponent at 0x7f25b62cad00>: {'u': <lems.model.component.Exposure at 0x7f25b5f57400>,
+  'iSyn': <lems.model.component.Exposure at 0x7f25b607a670>,
+  'iMemb': <lems.model.component.Exposure at 0x7f25b607aa00>,
+  'v': <lems.model.component.Exposure at 0x7f25b6500220>},
+ <lems.model.component.FatComponent at 0x7f25b62cadf0>: {'i': <lems.model.component.Exposure at 0x7f25dc921e80>},
+ <lems.model.component.FatComponent at 0x7f25b62caf70>: {'i': <lems.model.component.Exposure at 0x7f25dc921e80>},
+ <lems.model.component.FatComponent at 0x7f25b5fc2ac0>: {'i': <lems.model.component.Exposure at 0x7f25dc921e80>},
+ <lems.model.component.FatComponent at 0x7f25b65be9d0>: {'i': <lems.model.component.Exposure at 0x7f25dc921e80>},
+ <lems.model.component.FatComponent at 0x7f25b65bed00>: {'i': <lems.model.component.Exposure at 0x7f25dc921e80>},
+..
+}
+
+
+

This second function is primarily for use by the list_recording_paths_for_exposures function.

+

As noted in the helper documentation, these are both based on a function of the same name implemented in PyLEMS, version 0.5.8+.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Publications.html b/Userdocs/Publications.html new file mode 100644 index 00000000..86b12c8b --- /dev/null +++ b/Userdocs/Publications.html @@ -0,0 +1,888 @@ + + + + + + + + + + + Citing NeuroML and related publications — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Citing NeuroML and related publications

+ +
+ +
+
+ + + + +
+ + + + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/QuantitiesAndRecording.html b/Userdocs/QuantitiesAndRecording.html new file mode 100644 index 00000000..e3ca9f49 --- /dev/null +++ b/Userdocs/QuantitiesAndRecording.html @@ -0,0 +1,700 @@ + + + + + + + + + + + Quantities and recording — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Quantities and recording

+ +
+ +
+
+ + + + +
+ +
+

Quantities and recording#

+

In LEMS and NeuroML, quantities from all exposures and all events can be recorded by referring to them using paths. +For examples, please see the Getting Started with NeuroML section.

+
+

Recording events#

+

In NeuroML, all events can be recorded to files declared using the EventOutputFile component. +Once an EventOutputFile has been declared, events to record can be selected using the EventSelection component.

+

pyNeuroML provides the create_event_output_file function to create a EventOutputFile to record events to, and the add_selection_to_event_output_file function to record events to the declared data file(s).

+
+
+

Recording quantities from exposures#

+

In NeuroML, all quantities can be recorded to files declared using the OutputFile component. +Once the OutputFile has been declared, quantities to record can be selected using the OutputColumn component.

+

pyNeuroML provides the create_output_file function to create a OutputFile to record quantities to, and the add_column_to_output_file function to select quantities to record to the declared data file(s).

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Cells.html b/Userdocs/Schemas/Cells.html new file mode 100644 index 00000000..1b31775e --- /dev/null +++ b/Userdocs/Schemas/Cells.html @@ -0,0 +1,9258 @@ + + + + + + + + + + + Cells — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Cells#

+

Defines both abstract cell models ( e.g. izhikevichCell, adaptive exponential integrate and fire cell, adExIaFCell ), point conductance based cell models ( pointCellCondBased, pointCellCondBasedCa ) and cells models ( cell ) which specify the morphology ( containing segments ) and biophysicalProperties separately.

+
+

Original ComponentType definitions: Cells.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

baseCell#

+

extends baseStandalone

+

Base type of any cell ( e.g. point neuron like izhikevich2007Cell, or a morphologically detailed cell with segments ) which can be used in a population.

+
+ +
+
<xs:complexType name="BaseCell">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseCell
+
+variable = BaseCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

baseSpikingCell#

+

extends baseCell

+

Base type of any cell which can emit spike events.

+
+ +
+ +++++ + + + + + + +

spike

Spike event

Direction: out

+
+
+
+
+

baseCellMembPot#

+

extends baseSpikingCell

+

Any spiking cell which has a membrane potential v with units of voltage ( as opposed to a dimensionless membrane potential used in baseCellMembPotDL ).

+
+ +
+ +++++ + + + + + + +

v

Membrane potential

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+
+
+
+

baseCellMembPotDL#

+

extends baseSpikingCell

+

Any spiking cell which has a dimensioness membrane potential, V ( as opposed to a membrane potential units of voltage, baseCellMembPot ).

+
+ +
+ +++++ + + + + + + +

V

Membrane potential

Dimensionless

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+
+
+
+

baseChannelPopulation#

+

extends baseVoltageDepPointCurrent

+

Base type for any current produced by a population of channels, all of which are of type ionChannel.

+
+ +
+ +++++ + + + + + + +

ionChannel

baseIonChannel

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+
+
+
+

channelPopulation#

+

extends baseChannelPopulation

+

Population of a number of ohmic ion channels. These each produce a conductance channelg across a reversal potential erev, giving a total current i. Note that active membrane currents are more frequently specified as a density over an area of the cell using channelDensity.

+
+ +
+ +++++ + + + + + + + + + + +

erev

The reversal potential of the current produced

voltage

number

The number of channels present. This will be multiplied by the time varying conductance of the individual ion channel (which extends baseIonChannel) to produce the total conductance

Dimensionless

+
+ +
+ +++++ + + + + + + +

vShift = 0mV

voltage

+
+ +
+ ++++ + + + + + +

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

channelg = ionChannel->g

+
+

geff = channelg * number

+
+

i = geff * (erev - v) (exposed as i)

+
+
+
+ +
+
<xs:complexType name="ChannelPopulation">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="variableParameter" type="VariableParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="number" type="NonNegativeInteger" use="required"/>
+      <xs:attribute name="erev" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+      <xs:attribute name="segment" type="NonNegativeInteger" use="optional"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelPopulation
+
+variable = ChannelPopulation(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    number: 'a NonNegativeInteger (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+)
+
+
+
+ +
+
<channelPopulation id="naChansDend" ionChannel="NaConductance" segment="2" number="120000" erev="50mV" ion="na"/>
+
+
+
+
+
+
+

channelPopulationNernst#

+

extends baseChannelPopulation

+

Population of a number of channels with a time varying reversal potential erev determined by Nernst equation. Note: hard coded for Ca only!

+
+ +
+ +++++ + + + + + + +

number

The number of channels present. This will be multiplied by the time varying conductance of the individual ion channel (which extends baseIonChannel) to produce the total conductance

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

R = 8.3144621 J_per_K_per_mol

idealGasConstantDims

zCa = 2

Dimensionless

F = 96485.3 C_per_mol

charge_per_mole

vShift = 0mV

voltage

+
+ +
+ ++++ + + + + + +

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + + + + + +

erev

The reversal potential of the current produced, calculated from _caConcExt and _caConc

voltage

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

caConc

The internal Ca2+ concentration, as calculated/exposed by the parent Component

concentration

caConcExt

The external Ca2+ concentration, as calculated/exposed by the parent Component

concentration

temperature

The temperature to use in the calculation of _erev. Note this is generally exposed by a networkWithTemperature.

temperature

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

singleChannelConductance = ionChannel->g

+
+

totalConductance = singleChannelConductance * number

+
+

erev = (R * temperature / (zCa * F)) * log(caConcExt / caConc) (exposed as erev)

+
+

i = totalConductance * (erev - v) (exposed as i)

+
+
+
+
+
+
+

baseChannelDensity#

+

Base type for a current of density iDensity distributed on an area of a cell, flowing through the specified ionChannel. Instances of this ( normally channelDensity ) are specified in the membraneProperties of the cell.

+
+ +
+ +++++ + + + + + + +

ionChannel

baseIonChannel

+
+ +
+ +++++ + + + + + + +

iDensity

currentDensity

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+
+
+
+

baseChannelDensityCond#

+

extends baseChannelDensity

+

Base type for distributed conductances on an area of a cell producing a ( not necessarily ohmic ) current.

+
+ +
+ +++++ + + + + + + +

condDensity

conductanceDensity

+
+ +
+ +++++ + + + + + + + + + + +

gDensity

conductanceDensity

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + +

v

(from baseChannelDensity)

voltage

+
+
+
+
+

variableParameter#

+

Specifies a parameter ( e.g. condDensity ) which can vary its value across a segmentGroup. The value is calculated from value attribute of the inhomogeneousValue subelement. This element is normally a child of channelDensityNonUniform, channelDensityNonUniformNernst or channelDensityNonUniformGHK and is used to calculate the value of the conductance, etc. which will vary on different parts of the cell. The segmentGroup specified here needs to define an inhomogeneousParameter ( referenced from inhomogeneousParameter in the inhomogeneousValue ), which calculates a variable ( e.g. p ) varying across the cell ( e.g. based on the path length from soma ), which is then used in the value attribute of the inhomogeneousValue ( so for example condDensity = f( p ) ).

+
+ +
+ ++++ + + + + + + + + +

parameter

segmentGroup

+
+ +
+ +++++ + + + + + + +

inhomogeneousValue

inhomogeneousValue

+
+ +
+
<xs:complexType name="VariableParameter">
+  <xs:sequence>
+    <xs:element name="inhomogeneousValue" type="InhomogeneousValue" minOccurs="0"/>
+  </xs:sequence>
+  <xs:attribute name="parameter" type="xs:string" use="required"/>
+  <xs:attribute name="segmentGroup" type="xs:string" use="required"/>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import VariableParameter
+
+variable = VariableParameter(
+    parameter: 'a string (required)' = None,
+    segment_groups: 'a string (required)' = None,
+    inhomogeneous_value: 'a InhomogeneousValue (optional)' = None,
+)
+
+
+
+ +
+
<variableParameter parameter="condDensity" segmentGroup="dendrite_group">
+                        <inhomogeneousValue inhomogeneousParameter="dendrite_group_x1" value="5e-7 * exp(-p/200)"/>  
+                    </variableParameter>
+
+
+
+
+
+
+

inhomogeneousValue#

+

Specifies the value of an inhomogeneousParameter. For usage see variableParameter.

+
+ +
+ ++++ + + + + + + + + +

inhomogeneousParameter

value

+
+ +
+
<xs:complexType name="InhomogeneousValue">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="inhomogeneousParameter" type="xs:string" use="required"/>
+      <xs:attribute name="value" type="xs:string" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import InhomogeneousValue
+
+variable = InhomogeneousValue(
+    inhomogeneous_parameters: 'a string (required)' = None,
+    value: 'a string (required)' = None,
+)
+
+
+
+ +
+
<inhomogeneousValue inhomogeneousParameter="dendrite_group_x1" value="5e-7 * exp(-p/200)"/>
+
+
+
+
+
+
+

channelDensityNonUniform#

+

extends baseChannelDensity

+

Specifies a time varying ohmic conductance density, which is distributed on a region of the cell. The conductance density of the channel is not uniform, but is set using the variableParameter. Note, there is no dynamical description of this in LEMS yet, as this type only makes sense for multicompartmental cells. A ComponentType for this needs to be present to enable export of NeuroML 2 multicompartmental cells via LEMS/jNeuroML to NEURON.

+
+ +
+ +++++ + + + + + + +

erev

The reversal potential of the current produced

voltage

+
+ +
+ +++++ + + + + + + +

ZERO_CURR_DENS = 0 A_per_m2

currentDensity

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + +

variableParameter

variableParameter

+
+ +
+ +++++ + + + + + + +

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + +

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

iDensity = ZERO_CURR_DENS (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityNonUniform">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="variableParameter" type="VariableParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="erev" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityNonUniform
+
+variable = ChannelDensityNonUniform(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+)
+
+
+
+ +
+
<channelDensityNonUniform id="nonuniform_na_chans" ionChannel="NaConductance" erev="50mV" ion="na">
+                    <variableParameter parameter="condDensity" segmentGroup="dendrite_group">
+                        <inhomogeneousValue inhomogeneousParameter="dendrite_group_x1" value="5e-7 * exp(-p/200)"/>  
+                    </variableParameter>
+                </channelDensityNonUniform>
+
+
+
+
+
+
+

channelDensityNonUniformNernst#

+

extends baseChannelDensity

+

Specifies a time varying conductance density, which is distributed on a region of the cell, and whose reversal potential is calculated from the Nernst equation. Hard coded for Ca only!. The conductance density of the channel is not uniform, but is set using the variableParameter. Note, there is no dynamical description of this in LEMS yet, as this type only makes sense for multicompartmental cells. A ComponentType for this needs to be present to enable export of NeuroML 2 multicompartmental cells via LEMS/jNeuroML to NEURON.

+
+ +
+ +++++ + + + + + + +

ZERO_CURR_DENS = 0 A_per_m2

currentDensity

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + +

variableParameter

variableParameter

+
+ +
+ +++++ + + + + + + +

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + +

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

iDensity = ZERO_CURR_DENS (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityNonUniformNernst">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="variableParameter" type="VariableParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityNonUniformNernst
+
+variable = ChannelDensityNonUniformNernst(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+)
+
+
+
+
+
+
+

channelDensityNonUniformGHK#

+

extends baseChannelDensity

+

Specifies a time varying conductance density, which is distributed on a region of the cell, and whose current is calculated from the Goldman-Hodgkin-Katz equation. Hard coded for Ca only!. The conductance density of the channel is not uniform, but is set using the variableParameter. Note, there is no dynamical description of this in LEMS yet, as this type only makes sense for multicompartmental cells. A ComponentType for this needs to be present to enable export of NeuroML 2 multicompartmental cells via LEMS/jNeuroML to NEURON.

+
+ +
+ +++++ + + + + + + +

ZERO_CURR_DENS = 0 A_per_m2

currentDensity

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + +

variableParameter

variableParameter

+
+ +
+ +++++ + + + + + + +

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + +

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

iDensity = ZERO_CURR_DENS (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityNonUniformGHK">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="variableParameter" type="VariableParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityNonUniformGHK
+
+variable = ChannelDensityNonUniformGHK(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+)
+
+
+
+
+
+
+

channelDensity#

+

extends baseChannelDensityCond

+

Specifies a time varying ohmic conductance density, gDensity, which is distributed on an area of the cell ( specified in membraneProperties ) with fixed reversal potential erev producing a current density iDensity.

+
+ +
+ +++++ + + + + + + + + + + +

condDensity

(from baseChannelDensityCond)

conductanceDensity

erev

The reversal potential of the current produced

voltage

+
+ +
+ +++++ + + + + + + +

vShift = 0mV

voltage

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

Which segmentGroup the channelDensity is placed on. If this is missing, it implies it is placed on all _segment_s of the cell

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + + + + + +

gDensity

(from baseChannelDensityCond)

conductanceDensity

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + +

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

channelf = ionChannel->fopen

+
+

gDensity = condDensity * channelf (exposed as gDensity)

+
+

iDensity = gDensity * (erev - v) (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensity">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="variableParameter" type="VariableParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="condDensity" type="Nml2Quantity_conductanceDensity" use="optional"/>
+      <xs:attribute name="erev" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+      <xs:attribute name="segment" type="NonNegativeInteger" use="optional"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensity
+
+variable = ChannelDensity(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<channelDensity id="pasChans" ionChannel="pas" condDensity="3.0 S_per_m2" erev="-70mV" ion="non_specific"/>
+
+
+
<channelDensity id="naChansSoma" ionChannel="NaConductance" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" erev="50mV" ion="na"/>
+
+
+
<channelDensity id="naChans" ionChannel="HH_Na" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" ion="na" erev="50mV"/>
+
+
+
+
+
+
+

channelDensityVShift#

+

extends channelDensity

+

Same as channelDensity, but with a vShift parameter to change voltage activation of gates. The exact usage of vShift in expressions for rates is determined by the individual gates.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

condDensity

(from baseChannelDensityCond)

conductanceDensity

erev

The reversal potential of the current produced (from channelDensity)

voltage

vShift

voltage

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

Which segmentGroup the channelDensity is placed on. If this is missing, it implies it is placed on all _segment_s of the cell

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + + + + + +

gDensity

(from baseChannelDensityCond)

conductanceDensity

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + +

v

(from baseChannelDensity)

voltage

+
+ +
+
<xs:complexType name="ChannelDensityVShift">
+  <xs:complexContent>
+    <xs:extension base="ChannelDensity">
+      <xs:attribute name="vShift" type="Nml2Quantity_voltage" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityVShift
+
+variable = ChannelDensityVShift(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+    v_shift: 'a Nml2Quantity_voltage (required)' = None,
+)
+
+
+
+
+
+
+

channelDensityNernst#

+

extends baseChannelDensityCond

+

Specifies a time varying conductance density, gDensity, which is distributed on an area of the cell, producing a current density iDensity and whose reversal potential is calculated from the Nernst equation. Hard coded for Ca only! See OpenSourceBrain/ghk-nernst.

+
+ +
+ +++++ + + + + + + +

condDensity

(from baseChannelDensityCond)

conductanceDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + +

R = 8.3144621 J_per_K_per_mol

idealGasConstantDims

zCa = 2

Dimensionless

F = 96485.3 C_per_mol

charge_per_mole

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

Which segmentGroup the channelDensityNernst is placed on. If this is missing, it implies it is placed on all _segment_s of the cell

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

erev

The reversal potential of the current produced, calculated from caConcExt and caConc

voltage

gDensity

(from baseChannelDensityCond)

conductanceDensity

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

caConc

concentration

caConcExt

concentration

temperature

temperature

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

channelf = ionChannel->fopen

+
+
Conditional Derived Variables

IF caConcExt > 0 THEN

+
+

gDensity = condDensity * channelf  (exposed as gDensity)

+
+

IF caConcExt <= 0 THEN

+
+

gDensity = 0  (exposed as gDensity)

+
+

IF caConcExt > 0 THEN

+
+

erev = (R * temperature / (zCa * F)) * log(caConcExt / caConc)  (exposed as erev)

+
+

IF caConcExt <= 0 THEN

+
+

erev = 0  (exposed as erev)

+
+

IF caConcExt > 0 THEN

+
+

iDensity = gDensity * (erev - v)  (exposed as iDensity)

+
+

IF caConcExt <= 0 THEN

+
+

iDensity = 0  (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityNernst">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="variableParameter" type="VariableParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="condDensity" type="Nml2Quantity_conductanceDensity" use="optional"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+      <xs:attribute name="segment" type="NmlId" use="optional"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityNernst
+
+variable = ChannelDensityNernst(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

channelDensityNernstCa2#

+

extends baseChannelDensityCond

+

This component is similar to the original component type channelDensityNernst but it is changed in order to have a reversal potential that depends on a second independent Ca++ pool ( ca2 ). See OpenSourceBrain/ghk-nernst.

+
+ +
+ +++++ + + + + + + +

condDensity

(from baseChannelDensityCond)

conductanceDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + +

R = 8.3144621 J_per_K_per_mol

idealGasConstantDims

zCa = 2

Dimensionless

F = 96485.3 C_per_mol

charge_per_mole

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

Which segmentGroup the channelDensityNernstCa2 is placed on. If this is missing, it implies it is placed on all _segment_s of the cell

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

erev

The reversal potential of the current produced

voltage

gDensity

(from baseChannelDensityCond)

conductanceDensity

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

caConc2

concentration

caConcExt2

concentration

temperature

temperature

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

channelf = ionChannel->fopen

+
+
Conditional Derived Variables

IF caConcExt2 > 0 THEN

+
+

gDensity = condDensity * channelf  (exposed as gDensity)

+
+

IF caConcExt2 <= 0 THEN

+
+

gDensity = 0  (exposed as gDensity)

+
+

IF caConcExt2 > 0 THEN

+
+

erev = (R * temperature / (zCa * F)) * log(caConcExt2 / caConc2)  (exposed as erev)

+
+

IF caConcExt2 <= 0 THEN

+
+

erev = 0  (exposed as erev)

+
+

IF caConcExt2 > 0 THEN

+
+

iDensity = gDensity * (erev - v)  (exposed as iDensity)

+
+

IF caConcExt2 <= 0 THEN

+
+

iDensity = 0  (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityNernstCa2">
+  <xs:complexContent>
+    <xs:extension base="ChannelDensityNernst">
+      </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityNernstCa2
+
+variable = ChannelDensityNernstCa2(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    variable_parameters: 'list of VariableParameter(s) (optional)' = None,
+)
+
+
+
+
+
+
+

channelDensityGHK#

+

extends baseChannelDensity

+

Specifies a time varying conductance density, gDensity, which is distributed on an area of the cell, producing a current density iDensity and whose reversal potential is calculated from the Goldman Hodgkin Katz equation. Hard coded for Ca only! See OpenSourceBrain/ghk-nernst.

+
+ +
+ +++++ + + + + + + +

permeability

permeability

+
+ +
+ +++++ + + + + + + + + + + + + + + +

R = 8.3144621 J_per_K_per_mol

idealGasConstantDims

zCa = 2

Dimensionless

F = 96485.3 C_per_mol

charge_per_mole

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

Which segmentGroup the channelDensityGHK is placed on. If this is missing, it implies it is placed on all _segment_s of the cell

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + +

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

caConc

concentration

caConcExt

concentration

temperature

temperature

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

K = (zCa * F) / (R * temperature)

+
+

expKv = exp(-1 * K * v)

+
+

channelf = ionChannel->fopen

+
+
Conditional Derived Variables

IF caConcExt > 0 THEN

+
+

iDensity = -1 * channelf * permeability * zCa * F * K * v * ( caConc - (caConcExt * expKv) ) / (1 - expKv)  (exposed as iDensity)

+
+

IF caConcExt <= 0 THEN

+
+

iDensity = 0  (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityGHK">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="permeability" type="Nml2Quantity_permeability" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+      <xs:attribute name="segment" type="NmlId" use="optional"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityGHK
+
+variable = ChannelDensityGHK(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    permeability: 'a Nml2Quantity_permeability (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+)
+
+
+
+
+
+
+

channelDensityGHK2#

+

extends baseChannelDensityCond

+

Time varying conductance density, gDensity, which is distributed on an area of the cell, producing a current density iDensity. Modified version of Jaffe et al. 1994 ( used also in Lawrence et al. 2006 ). See OpenSourceBrain/ghk-nernst.

+
+ +
+ +++++ + + + + + + +

condDensity

(from baseChannelDensityCond)

conductanceDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + +

VOLT_SCALE = 1 mV

voltage

CONC_SCALE = 1 mM

concentration

TEMP_SCALE = 1 K

temperature

+
+ +
+ ++++ + + + + + + + + +

segmentGroup

Which segmentGroup the channelDensityGHK2 is placed on. If this is missing, it implies it is placed on all _segment_s of the cell

ion

Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it’s here as it makes it easier to select channelPopulations transmitting specific ions.

+
+ +
+ +++++ + + + + + + + + + + +

gDensity

(from baseChannelDensityCond)

conductanceDensity

iDensity

(from baseChannelDensity)

currentDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

caConc

concentration

caConcExt

concentration

temperature

temperature

v

(from baseChannelDensity)

voltage

+
+ +
+
+
Structure

CHILD INSTANCE: ionChannel

+
+
Derived Variables

V = v / VOLT_SCALE

+
+

ca_conc_i = caConc / CONC_SCALE

+
+

ca_conc_ext = caConcExt / CONC_SCALE

+
+

T = temperature / TEMP_SCALE

+
+

channelf = ionChannel->fopen

+
+

gDensity = condDensity * channelf (exposed as gDensity)

+
+

tmp = (25 * T) / (293.15 * 2)

+
+
Conditional Derived Variables

IF V/tmp = 0. THEN

+
+

pOpen = tmp * 1e-3 * (1 - ((ca_conc_i/ca_conc_ext) * exp(V/tmp))) * (1 - (V/tmp)/2)

+
+

IF V/tmp != 0. THEN

+
+

pOpen = tmp * 1e-3 * (1 - ((ca_conc_i/ca_conc_ext) * exp(V/tmp))) * ((V/tmp) / (exp(V/tmp) - 1))

+
+

IF ca_conc_ext > 0 THEN

+
+

iDensity = gDensity * pOpen  (exposed as iDensity)

+
+

IF ca_conc_ext <= 0 THEN

+
+

iDensity = 0  (exposed as iDensity)

+
+
+
+ +
+
<xs:complexType name="ChannelDensityGHK2">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:attribute name="ionChannel" type="NmlId" use="required"/>
+      <xs:attribute name="condDensity" type="Nml2Quantity_conductanceDensity" use="optional"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+      <xs:attribute name="segment" type="NmlId" use="optional"/>
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ChannelDensityGHK2
+
+variable = ChannelDensityGHK2(
+    id: 'a NmlId (required)' = None,
+    ion_channel: 'a NmlId (required)' = None,
+    cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+    segments: 'a NonNegativeInteger (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+)
+
+
+
+
+
+
+

pointCellCondBased#

+

extends baseCellMembPotCap

+

Simple model of a conductance based cell, with no separate morphology element, just an absolute capacitance C, and a set of channel populations. Note: use of cell is generally preferable ( and more widely supported ), even for a single compartment cell.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

thresh

The voltage threshold above which the cell is considered to be _spiking

voltage

v0

The initial membrane potential of the cell

voltage

+
+ +
+ +++++ + + + + + + +

populations

baseChannelPopulation

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

spiking: Dimensionless

+
+
On Start

v = v0

+
+

spiking = 0

+
+
On Conditions

IF v > thresh AND spiking < 0.5 THEN

+
+

   spiking = 1

+
+

   EVENT OUT on port: spike

+
+

IF v < thresh THEN

+
+

   spiking = 0

+
+
Derived Variables

iChannels = populations[*]->i(reduce method: add)

+
+

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iMemb = iChannels + iSyn (exposed as iMemb)

+
+
Time Derivatives

d v /dt = iMemb / C

+
+
+
+
+
+
+

pointCellCondBasedCa#

+

extends baseCellMembPotCap

+

TEMPORARY: Point cell with conductances and Ca concentration info. Not yet fully tested!!! TODO: Remove in favour of cell.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

thresh

The voltage threshold above which the cell is considered to be _spiking

voltage

v0

The initial membrane potential of the cell

voltage

+
+ +
+ +++++ + + + + + + + + + + +

populations

baseChannelPopulation

concentrationModels

concentrationModel

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

caConc

concentration

iCa

current

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

spiking: Dimensionless

+
+
On Start

v = v0

+
+

spiking = 0

+
+
On Conditions

IF v > thresh AND spiking < 0.5 THEN

+
+

   spiking = 1

+
+

   EVENT OUT on port: spike

+
+

IF v < thresh THEN

+
+

   spiking = 0

+
+
Derived Variables

iChannels = populations[*]->i(reduce method: add)

+
+

iCa = populations[ion=‘ca’]->i(reduce method: add) (exposed as iCa)

+
+

caConc = concentrationModels[species=‘ca’]->concentration(reduce method: add) (exposed as caConc)

+
+

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iMemb = iChannels + iSyn (exposed as iMemb)

+
+
Time Derivatives

d v /dt = iMemb / C

+
+
+
+
+
+
+

distal#

+

extends point3DWithDiam

+

Point on a segment furthest from the soma. Should always be present in the description of a segment, unlike proximal.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

diameter

Diameter of the ppoint. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

x

x coordinate of the point. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

y

y coordinate of the ppoint. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

z

z coordinate of the ppoint. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

+
+ +
+ +++++ + + + + + + +

radius

A dimensional quantity given by half the _diameter. (from point3DWithDiam)

length

+

   radius = MICRON * diameter / 2

+ +++++ + + + + + + +

xLength

A version of _x with dimension length. (from point3DWithDiam)

length

+

   xLength = MICRON * x

+ +++++ + + + + + + +

yLength

A version of _y with dimension length. (from point3DWithDiam)

length

+

   yLength = MICRON * y

+ +++++ + + + + + + +

zLength

A version of _z with dimension length. (from point3DWithDiam)

length

+

   zLength = MICRON * z

+
+ +
+
<distal x="10" y="0" z="0" diameter="10"/>
+
+
+
<distal x="20" y="0" z="0" diameter="3"/>
+
+
+
<distal x="30" y="0" z="0" diameter="1"/>
+
+
+
+
+
+
+

proximal#

+

extends point3DWithDiam

+

Point on a segment closest to the soma. Note, the proximal point can be omitted, and in this case is defined as being the point fractionAlong between the proximal and distal point of the parent, i.e. if fractionAlong = 1 ( as it is by default ) it will be the distal on the parent, or if fractionAlong = 0, it will be the proximal point. If between 0 and 1, it is the linear interpolation between the two points.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

diameter

Diameter of the ppoint. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

x

x coordinate of the point. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

y

y coordinate of the ppoint. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

z

z coordinate of the ppoint. Note: no dimension used, see description of point3DWithDiam for details. (from point3DWithDiam)

Dimensionless

+
+ +
+ +++++ + + + + + + +

radius

A dimensional quantity given by half the _diameter. (from point3DWithDiam)

length

+

   radius = MICRON * diameter / 2

+ +++++ + + + + + + +

xLength

A version of _x with dimension length. (from point3DWithDiam)

length

+

   xLength = MICRON * x

+ +++++ + + + + + + +

yLength

A version of _y with dimension length. (from point3DWithDiam)

length

+

   yLength = MICRON * y

+ +++++ + + + + + + +

zLength

A version of _z with dimension length. (from point3DWithDiam)

length

+

   zLength = MICRON * z

+
+ +
+
<proximal x="0" y="0" z="0" diameter="10"/>
+
+
+
<proximal x="25" y="0" z="0" diameter="0.1"/>
+
+
+
<proximal x="0" y="0" z="0" diameter="10"/>
+
+
+
+
+
+
+

parent#

+

Specifies the segment which is this segment’s parent. The fractionAlong specifies where it is connected, usually 1 ( the default value ), meaning the distal point of the parent, or 0, meaning the proximal point. If it is between these, a linear interpolation between the 2 points should be used.

+
+ +
+ ++++ + + + + + + + + +

segment

The id of the parent segment

fractionAlong

The fraction along the the parent segment at which this segment is attached. For usage see proximal

+
+ +
+
<parent segment="0"/>
+
+
+
<parent segment="1"/>
+
+
+
<parent segment="2" fractionAlong="0.5"/>
+
+
+
+
+
+
+

segment#

+

A segment defines the smallest unit within a possibly branching structure ( morphology ), such as a dendrite or axon. Its id should be a nonnegative integer ( usually soma/root = 0 ). Its end points are given by the proximal and distal points. The proximal point can be omitted, usually because it is the same as a point on the parent segment, see proximal for details. parent specifies the parent segment. The first segment of a cell ( with no parent ) usually represents the soma. The shape is normally a cylinder ( radii of the proximal and distal equal, but positions different ) or a conical frustum ( radii and positions different ). If the x, y, x positions of the proximal and distal are equal, the segment can be interpreted as a sphere, and in this case the radii of these points must be equal. NOTE: LEMS does not yet support multicompartmental modelling, so the Dynamics here is only appropriate for single compartment modelling.

+
+ +
+ +++++ + + + + + + +

LEN = 1m

length

+
+ +
+ ++++ + + + + + +

name

An optional name for the segment. Convenient for providing a suitable variable name for generated code, e.g. soma, dend0

+
+ +
+ +++++ + + + + + + + + + + + + + + +

parent

parent

distal

distal

proximal

proximal

+
+ +
+ +++++ + + + + + + + + + + + + + + +

length

length

radDist

length

surfaceArea

area

+
+ +
+
+
Derived Variables

radDist = distal->radius (exposed as radDist)

+
+

dx = distal->xLength

+
+

dy = distal->yLength

+
+

dz = distal->zLength

+
+

px = proximal->xLength

+
+

py = proximal->yLength

+
+

pz = proximal->zLength

+
+

length = sqrt(((dx - px) * (dx - px) + (dy - py) * (dy - py) + (dz - pz) * (dz - pz))/(LEN * LEN)) * LEN (exposed as length)

+
+
Conditional Derived Variables

IF length = 0 * LEN THEN

+
+

surfaceArea = 4 * radDist * radDist * 3.14159265  (exposed as surfaceArea)

+
+

IF length > 0 * LEN THEN

+
+

surfaceArea = 2 * radDist * 3.14159265 * length  (exposed as surfaceArea)

+
+
+
+ +
+
<xs:complexType name="Segment">
+  <xs:complexContent>
+    <xs:extension base="BaseNonNegativeIntegerId">
+      <xs:sequence>
+        <xs:element name="parent" type="SegmentParent" minOccurs="0"/>
+        <xs:element name="proximal" type="Point3DWithDiam" minOccurs="0"/>
+        <xs:element name="distal" type="Point3DWithDiam" minOccurs="1"/>
+      </xs:sequence>
+      <xs:attribute name="name" type="xs:string" use="optional"/>
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Segment
+
+variable = Segment(
+    id: 'a NonNegativeInteger (required)' = None,
+    name: 'a string (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    parent: 'a SegmentParent (optional)' = None,
+    proximal: 'a Point3DWithDiam (optional)' = None,
+    distal: 'a Point3DWithDiam (required)' = None,
+)
+
+
+
+ +
+
<segment id="3" name="Spine1">
+                <parent segment="2" fractionAlong="0.5"/>
+                <proximal x="25" y="0" z="0" diameter="0.1"/>
+                <distal x="25" y="0.2" z="0" diameter="0.1"/>
+            </segment>
+
+
+
<segment id="0" name="Soma">
+                
+                <proximal x="0" y="0" z="0" diameter="10"/>
+                <distal x="10" y="0" z="0" diameter="10"/>
+            </segment>
+
+
+
<segment id="1" name="Dendrite1">
+                <parent segment="0"/>
+                
+                <distal x="20" y="0" z="0" diameter="3"/>
+            </segment>
+
+
+
+
+
+
+

segmentGroup#

+

A method to describe a group of segments in a morphology, e.g. soma_group, dendrite_group, axon_group. While a name is useful to describe the group, the neuroLexId attribute can be used to explicitly specify the meaning of the group, e.g. sao1044911821 for ‘Neuronal Cell Body’, sao1211023249 for ‘Dendrite’. The segments in this group can be specified as: a list of individual member segments; a path, all of the segments along which should be included; a subTree of the cell to include; other segmentGroups to include ( so all segments from those get included here ). An inhomogeneousParameter can be defined on the region of the cell specified by this group ( see variableParameter for usage ).

+
+ +
+ ++++ + + + + + +

neuroLexId

An id string for pointing to an entry in the NeuroLex ontology. Use of this attribute is a shorthand for a full RDF based reference to the MIRIAM Resource urn:miriam:neurolex, with an bqbiol:is qualifier.

+
+ +
+ +++++ + + + + + + + + + + +

notes

notes

annotation

annotation

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

property

property

members

member

paths

path

subTrees

subTree

includes

include

inhomogeneousParameter

inhomogeneousParameter

+
+ +
+
<xs:complexType name="SegmentGroup">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="annotation" type="Annotation" minOccurs="0"/>
+        <xs:element name="member" type="Member" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="include" type="Include" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="path" type="Path" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="subTree" type="SubTree" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="inhomogeneousParameter" type="InhomogeneousParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SegmentGroup
+
+variable = SegmentGroup(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    members: 'list of Member(s) (optional)' = None,
+    includes: 'list of Include(s) (optional)' = None,
+    paths: 'list of Path(s) (optional)' = None,
+    sub_trees: 'list of SubTree(s) (optional)' = None,
+    inhomogeneous_parameters: 'list of InhomogeneousParameter(s) (optional)' = None,
+)
+
+
+
+ +
+
<segmentGroup id="dendrite_group" neuroLexId="sao1211023249">    
+                <member segment="1"/>
+                <member segment="2"/>
+                <member segment="3"/>
+            </segmentGroup>
+
+
+
<segmentGroup id="soma_group" neuroLexId="sao1044911821">     
+                <member segment="0"/>
+            </segmentGroup>
+
+
+
<segmentGroup id="spines" neuroLexId="sao1145756102">    
+                <member segment="3"/>
+            </segmentGroup>
+
+
+
+
+
+
+

member#

+

A single identified segment which is part of the segmentGroup.

+
+ +
+ ++++ + + + + + +

segment

+
+ +
+
<xs:complexType name="Member">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="segment" type="NonNegativeInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Member
+
+variable = Member(
+    segments: 'a NonNegativeInteger (required)' = None,
+)
+
+
+
+ +
+
<member segment="0"/>
+
+
+
<member segment="1"/>
+
+
+
<member segment="2"/>
+
+
+
+
+
+
+

from#

+

In a path or subTree, specifies which segment ( inclusive ) from which to calculate the segmentGroup.

+
+ +
+ ++++ + + + + + +

segment

+
+ +
+
<from segment="1"/>
+
+
+
<from segment="1"/>
+
+
+
+
+
+
+

to#

+

In a path, specifies which segment ( inclusive ) up to which to calculate the segmentGroup.

+
+ +
+ ++++ + + + + + +

segment

+
+ +
+
<to segment="2"/>
+
+
+
+
+
+
+

include#

+

Include all members of another segmentGroup in this group.

+
+ +
+ ++++ + + + + + + + + +

href

TODO: fix this!!! This is needed here, since include is used to include external nml files!!

segmentGroup

+
+ +
+
<xs:complexType name="Include">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="segmentGroup" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Include
+
+variable = Include(
+    segment_groups: 'a NmlId (required)' = None,
+)
+
+
+
+ +
+
<include href="NML2_SingleCompHHCell.nml"/>
+
+
+
<include href="NML2_SimpleIonChannel.nml"/>
+
+
+
<include href="NML2_SimpleIonChannel.nml"/>
+
+
+
+
+
+
+

path#

+

Include all the segments between those specified by from and to, inclusive.

+
+ +
+ +++++ + + + + + + + + + + +

from

from

to

to

+
+ +
+
<xs:complexType name="Path">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:sequence>
+        <xs:element name="from" type="SegmentEndPoint" minOccurs="0"/>
+        <xs:element name="to" type="SegmentEndPoint" minOccurs="0"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Path
+
+variable = Path(
+    from_: 'a SegmentEndPoint (optional)' = None,
+    to: 'a SegmentEndPoint (optional)' = None,
+)
+
+
+
+ +
+
<path>
+                    <from segment="1"/>
+                    <to segment="2"/>
+                </path>
+
+
+
+
+
+
+

subTree#

+

Include all the segments distal to that specified by from in the segmentGroup.

+
+ +
+ +++++ + + + + + + +

from

from

+
+ +
+
<xs:complexType name="SubTree">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:choice>
+        <xs:element name="from" type="SegmentEndPoint" minOccurs="0"/>
+        <xs:element name="to" type="SegmentEndPoint" minOccurs="0"/>
+      </xs:choice>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SubTree
+
+variable = SubTree(
+    from_: 'a SegmentEndPoint (optional)' = None,
+    to: 'a SegmentEndPoint (optional)' = None,
+)
+
+
+
+ +
+
<subTree>
+                    <from segment="1"/>
+                </subTree>
+
+
+
+
+
+
+

inhomogeneousParameter#

+

An inhomogeneous parameter specified across the segmentGroup ( see variableParameter for usage ).

+
+ +
+ ++++ + + + + + + + + +

variable

metric

+
+ +
+ +++++ + + + + + + + + + + +

proximal

proximalDetails

distal

distalDetails

+
+ +
+
<xs:complexType name="InhomogeneousParameter">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="proximal" type="ProximalDetails" minOccurs="0"/>
+        <xs:element name="distal" type="DistalDetails" minOccurs="0"/>
+      </xs:sequence>
+      <xs:attribute name="variable" type="xs:string" use="required"/>
+      <xs:attribute name="metric" type="Metric" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import InhomogeneousParameter
+
+variable = InhomogeneousParameter(
+    id: 'a NmlId (required)' = None,
+    variable: 'a string (required)' = None,
+    metric: 'a Metric (required)' = None,
+    proximal: 'a ProximalDetails (optional)' = None,
+    distal: 'a DistalDetails (optional)' = None,
+)
+
+
+
+ +
+
<inhomogeneousParameter id="dendrite_group_x2" variable="r" metric="Path Length from root">
+                        <proximal translationStart="0"/>
+                        <distal normalizationEnd="1"/>
+                </inhomogeneousParameter>
+
+
+
<inhomogeneousParameter id="dendrite_group_x1" variable="p" metric="Path Length from root"/>
+
+
+
+
+
+
+

proximalDetails#

+

What to do at the proximal point when creating an inhomogeneous parameter.

+
+ +
+ ++++ + + + + + +

translationStart

+
+ +
+
<xs:complexType name="ProximalDetails">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="translationStart" type="xs:double" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ProximalDetails
+
+variable = ProximalDetails(
+    translation_start: 'a double (required)' = None,
+)
+
+
+
+
+
+
+

distalDetails#

+

What to do at the distal point when creating an inhomogeneous parameter.

+
+ +
+ ++++ + + + + + +

normalizationEnd

+
+ +
+
<xs:complexType name="DistalDetails">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="normalizationEnd" type="xs:double" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import DistalDetails
+
+variable = DistalDetails(
+    normalization_end: 'a double (required)' = None,
+)
+
+
+
+
+
+
+

morphology#

+

The collection of segments which specify the 3D structure of the cell, along with a number of segmentGroups.

+
+ +
+ +++++ + + + + + + + + + + +

segments

segment

segmentGroups

segmentGroup

+
+ +
+
<xs:complexType name="Morphology">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="segment" type="Segment" maxOccurs="unbounded"/>
+        <xs:element name="segmentGroup" type="SegmentGroup" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Morphology
+
+variable = Morphology(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    segments: 'list of Segment(s) (required)' = None,
+    segment_groups: 'list of SegmentGroup(s) (optional)' = None,
+)
+
+
+
+ +
+
<morphology id="SpikingCell_morphology">
+            <segment id="0" name="Soma">
+                
+                <proximal x="0" y="0" z="0" diameter="10"/>
+                <distal x="10" y="0" z="0" diameter="10"/>
+            </segment>
+            <segment id="1" name="Dendrite1">
+                <parent segment="0"/>
+                
+                <distal x="20" y="0" z="0" diameter="3"/>
+            </segment>
+            <segment id="2" name="Dendrite2">
+                <parent segment="1"/>
+                <distal x="30" y="0" z="0" diameter="1"/>
+            </segment>
+            <segment id="3" name="Spine1">
+                <parent segment="2" fractionAlong="0.5"/>
+                <proximal x="25" y="0" z="0" diameter="0.1"/>
+                <distal x="25" y="0.2" z="0" diameter="0.1"/>
+            </segment>
+            
+            <segmentGroup id="soma_group" neuroLexId="sao1044911821">     
+                <member segment="0"/>
+            </segmentGroup>
+            <segmentGroup id="dendrite_group" neuroLexId="sao1211023249">    
+                <member segment="1"/>
+                <member segment="2"/>
+                <member segment="3"/>
+            </segmentGroup>
+            <segmentGroup id="spines" neuroLexId="sao1145756102">    
+                <member segment="3"/>
+            </segmentGroup>
+        </morphology>
+
+
+
<morphology id="NeuroMorpho_PyrCell123">  
+        <segment id="0" name="Soma">
+            
+            <proximal x="0" y="0" z="0" diameter="10"/>
+            <distal x="10" y="0" z="0" diameter="10"/>
+        </segment>
+        
+    </morphology>
+
+
+
<morphology id="SimpleCell_Morphology">
+            
+            <segment id="0" name="Soma">    
+                
+                <proximal x="0" y="0" z="0" diameter="10"/>
+                <distal x="10" y="0" z="0" diameter="10"/>
+            </segment>
+            <segment id="1" name="MainDendrite1">
+                <parent segment="0"/>
+                
+                <proximal x="10" y="0" z="0" diameter="3"/> 
+                <distal x="20" y="0" z="0" diameter="3"/>
+            </segment>
+            <segment id="2" name="MainDendrite2">
+                <parent segment="1"/>
+                
+                <distal x="30" y="0" z="0" diameter="1"/>
+            </segment>
+            
+            <segmentGroup id="soma_group" neuroLexId="sao1044911821">    
+                <member segment="0"/>
+            </segmentGroup>
+            <segmentGroup id="dendrite_group" neuroLexId="sao1211023249">
+                <member segment="1"/>
+                <member segment="2"/>
+                
+                <inhomogeneousParameter id="dendrite_group_x1" variable="p" metric="Path Length from root"/>
+ 
+                <inhomogeneousParameter id="dendrite_group_x2" variable="r" metric="Path Length from root">
+                        <proximal translationStart="0"/>
+                        <distal normalizationEnd="1"/>
+                </inhomogeneousParameter>
+                
+            </segmentGroup>
+        </morphology>
+
+
+
+
+
+
+

specificCapacitance#

+

Capacitance per unit area.

+
+ +
+ +++++ + + + + + + +

value

specificCapacitance

+
+ +
+ ++++ + + + + + +

segmentGroup

+
+ +
+ +++++ + + + + + + +

specCap

specificCapacitance

+
+ +
+
+
Derived Variables

specCap = value (exposed as specCap)

+
+
+
+ +
+
<xs:complexType name="SpecificCapacitance">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="value" type="Nml2Quantity_specificCapacitance" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpecificCapacitance
+
+variable = SpecificCapacitance(
+    value: 'a Nml2Quantity_specificCapacitance (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+)
+
+
+
+ +
+
<specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+
+
+
<specificCapacitance segmentGroup="dendrite_group" value="2.0 uF_per_cm2"/>
+
+
+
<specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+
+
+
+
+
+
+

initMembPotential#

+

Explicitly set initial membrane potential for the cell.

+
+ +
+ +++++ + + + + + + +

value

voltage

+
+ +
+
<xs:complexType name="InitMembPotential">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="value" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import InitMembPotential
+
+variable = InitMembPotential(
+    value: 'a Nml2Quantity_voltage (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+)
+
+
+
+ +
+
<initMembPotential value="-65mV"/>
+
+
+
<initMembPotential value="-65mV"/>
+
+
+
+
+
+
+

spikeThresh#

+

Membrane potential at which to emit a spiking event. Note, usually the spiking event will not be emitted again until the membrane potential has fallen below this value and rises again to cross it in a positive direction.

+
+ +
+ +++++ + + + + + + +

value

voltage

+
+ +
+
<xs:complexType name="SpikeThresh">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="value" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeThresh
+
+variable = SpikeThresh(
+    value: 'a Nml2Quantity_voltage (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+)
+
+
+
+ +
+
<spikeThresh value="-20mV"/>
+
+
+
<spikeThresh value="-20mV"/>
+
+
+
+
+
+
+

membraneProperties#

+

Properties specific to the membrane, such as the populations of channels, channelDensities, specificCapacitance, etc.

+
+ +
+ +++++ + + + + + + + + + + +

initMembPotential

initMembPotential

spikeThresh

spikeThresh

+
+ +
+ +++++ + + + + + + + + + + + + + + +

specificCapacitances

specificCapacitance

populations

baseChannelPopulation

channelDensities

baseChannelDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iCa

current

totChanCurrent

current

totSpecCap

specificCapacitance

+
+ +
+ +++++ + + + + + + +

surfaceArea

area

+
+ +
+
+
Derived Variables

totSpecCap = specificCapacitances[*]->specCap(reduce method: add) (exposed as totSpecCap)

+
+

totChanPopCurrent = populations[*]->i(reduce method: add)

+
+

totChanDensCurrentDensity = channelDensities[*]->iDensity(reduce method: add)

+
+

totChanCurrent = totChanPopCurrent + (totChanDensCurrentDensity * surfaceArea) (exposed as totChanCurrent)

+
+

totChanPopCurrentCa = populations[ion=‘ca’]->i(reduce method: add)

+
+

totChanDensCurrentDensityCa = channelDensities[ion=‘ca’]->iDensity(reduce method: add)

+
+

iCa = totChanPopCurrentCa + (totChanDensCurrentDensityCa * surfaceArea) (exposed as iCa)

+
+
+
+ +
+
<xs:complexType name="MembraneProperties">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:sequence>
+        <xs:element name="channelPopulation" type="ChannelPopulation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensity" type="ChannelDensity" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityVShift" type="ChannelDensityVShift" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityNernst" type="ChannelDensityNernst" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityGHK" type="ChannelDensityGHK" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityGHK2" type="ChannelDensityGHK2" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityNonUniform" type="ChannelDensityNonUniform" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityNonUniformNernst" type="ChannelDensityNonUniformNernst" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="channelDensityNonUniformGHK" type="ChannelDensityNonUniformGHK" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="spikeThresh" type="SpikeThresh" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="specificCapacitance" type="SpecificCapacitance" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="initMembPotential" type="InitMembPotential" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import MembraneProperties
+
+variable = MembraneProperties(
+    channel_populations: 'list of ChannelPopulation(s) (optional)' = None,
+    channel_densities: 'list of ChannelDensity(s) (optional)' = None,
+    channel_density_v_shifts: 'list of ChannelDensityVShift(s) (optional)' = None,
+    channel_density_nernsts: 'list of ChannelDensityNernst(s) (optional)' = None,
+    channel_density_ghks: 'list of ChannelDensityGHK(s) (optional)' = None,
+    channel_density_ghk2s: 'list of ChannelDensityGHK2(s) (optional)' = None,
+    channel_density_non_uniforms: 'list of ChannelDensityNonUniform(s) (optional)' = None,
+    channel_density_non_uniform_nernsts: 'list of ChannelDensityNonUniformNernst(s) (optional)' = None,
+    channel_density_non_uniform_ghks: 'list of ChannelDensityNonUniformGHK(s) (optional)' = None,
+    spike_threshes: 'list of SpikeThresh(s) (optional)' = None,
+    specific_capacitances: 'list of SpecificCapacitance(s) (optional)' = None,
+    init_memb_potentials: 'list of InitMembPotential(s) (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<membraneProperties>
+                <channelPopulation id="naChansDend" ionChannel="NaConductance" segment="2" number="120000" erev="50mV" ion="na"/>   
+                <channelDensity id="pasChans" ionChannel="pas" condDensity="3.0 S_per_m2" erev="-70mV" ion="non_specific"/> 
+                <channelDensity id="naChansSoma" ionChannel="NaConductance" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" erev="50mV" ion="na"/>
+                <specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+                <specificCapacitance segmentGroup="dendrite_group" value="2.0 uF_per_cm2"/>
+            </membraneProperties>
+
+
+
<membraneProperties> 
+        
+            
+            <channelDensity id="naChans" ionChannel="HH_Na" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" ion="na" erev="50mV"/>  
+            <!-- Ions present inside the cell. Note: a fixed reversal potential is specified here  
+            <reversalPotential species="na" value="50mV"/>
+            <reversalPotential species="k" value="-77mV"/>-->
+            
+        </membraneProperties>
+
+
+
<membraneProperties>
+                <channelDensityNonUniform id="nonuniform_na_chans" ionChannel="NaConductance" erev="50mV" ion="na">
+                    <variableParameter parameter="condDensity" segmentGroup="dendrite_group">
+                        <inhomogeneousValue inhomogeneousParameter="dendrite_group_x1" value="5e-7 * exp(-p/200)"/>  
+                    </variableParameter>
+                </channelDensityNonUniform>
+                <specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+            </membraneProperties>
+
+
+
+
+
+
+

membraneProperties2CaPools#

+

extends membraneProperties

+

Variant of membraneProperties with 2 independent Ca pools.

+
+ +
+ +++++ + + + + + + + + + + +

initMembPotential

initMembPotential

spikeThresh

spikeThresh

+
+ +
+ +++++ + + + + + + + + + + + + + + +

specificCapacitances

specificCapacitance

populations

baseChannelPopulation

channelDensities

baseChannelDensity

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

iCa

(from membraneProperties)

current

iCa2

current

totChanCurrent

(from membraneProperties)

current

totSpecCap

(from membraneProperties)

specificCapacitance

+
+ +
+ +++++ + + + + + + + + + + +

surfaceArea

area

surfaceArea

(from membraneProperties)

area

+
+ +
+
+
Derived Variables

totSpecCap = specificCapacitances[*]->specCap(reduce method: add) (exposed as totSpecCap)

+
+

totChanPopCurrent = populations[*]->i(reduce method: add)

+
+

totChanDensCurrentDensity = channelDensities[*]->iDensity(reduce method: add)

+
+

totChanCurrent = totChanPopCurrent + (totChanDensCurrentDensity * surfaceArea) (exposed as totChanCurrent)

+
+

totChanPopCurrentCa = populations[ion=‘ca’]->i(reduce method: add)

+
+

totChanDensCurrentDensityCa = channelDensities[ion=‘ca’]->iDensity(reduce method: add)

+
+

iCa = totChanPopCurrentCa + (totChanDensCurrentDensityCa * surfaceArea) (exposed as iCa)

+
+

totChanPopCurrentCa2 = populations[ion=‘ca2’]->i(reduce method: add)

+
+

totChanDensCurrentDensityCa2 = channelDensities[ion=‘ca2’]->iDensity(reduce method: add)

+
+

iCa2 = totChanPopCurrentCa2 + (totChanDensCurrentDensityCa2 * surfaceArea) (exposed as iCa2)

+
+
+
+ +
+
<xs:complexType name="MembraneProperties2CaPools">
+  <xs:complexContent>
+    <xs:extension base="MembraneProperties">
+      <xs:sequence>
+        <xs:element name="channelDensityNernstCa2" type="ChannelDensityNernstCa2" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import MembraneProperties2CaPools
+
+variable = MembraneProperties2CaPools(
+    channel_populations: 'list of ChannelPopulation(s) (optional)' = None,
+    channel_densities: 'list of ChannelDensity(s) (optional)' = None,
+    channel_density_v_shifts: 'list of ChannelDensityVShift(s) (optional)' = None,
+    channel_density_nernsts: 'list of ChannelDensityNernst(s) (optional)' = None,
+    channel_density_ghks: 'list of ChannelDensityGHK(s) (optional)' = None,
+    channel_density_ghk2s: 'list of ChannelDensityGHK2(s) (optional)' = None,
+    channel_density_non_uniforms: 'list of ChannelDensityNonUniform(s) (optional)' = None,
+    channel_density_non_uniform_nernsts: 'list of ChannelDensityNonUniformNernst(s) (optional)' = None,
+    channel_density_non_uniform_ghks: 'list of ChannelDensityNonUniformGHK(s) (optional)' = None,
+    spike_threshes: 'list of SpikeThresh(s) (optional)' = None,
+    specific_capacitances: 'list of SpecificCapacitance(s) (optional)' = None,
+    init_memb_potentials: 'list of InitMembPotential(s) (optional)' = None,
+    channel_density_nernst_ca2s: 'list of ChannelDensityNernstCa2(s) (optional)' = None,
+)
+
+
+
+
+
+
+

biophysicalProperties#

+

The biophysical properties of the cell, including the membraneProperties and the intracellularProperties.

+
+ +
+ +++++ + + + + + + + + + + +

membraneProperties

membraneProperties

intracellularProperties

intracellularProperties

+
+ +
+ +++++ + + + + + + +

totSpecCap

specificCapacitance

+
+ +
+
+
Derived Variables

totSpecCap = membraneProperties->totSpecCap (exposed as totSpecCap)

+
+
+
+ +
+
<xs:complexType name="BiophysicalProperties">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="membraneProperties" type="MembraneProperties"/>
+        <xs:element name="intracellularProperties" type="IntracellularProperties" minOccurs="0"/>
+        <xs:element name="extracellularProperties" type="ExtracellularProperties" minOccurs="0"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BiophysicalProperties
+
+variable = BiophysicalProperties(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    membrane_properties: 'a MembraneProperties (required)' = None,
+    intracellular_properties: 'a IntracellularProperties (optional)' = None,
+    extracellular_properties: 'a ExtracellularProperties (optional)' = None,
+)
+
+
+
+ +
+
<biophysicalProperties id="bio_cell">
+            <membraneProperties>
+                <channelPopulation id="naChansDend" ionChannel="NaConductance" segment="2" number="120000" erev="50mV" ion="na"/>   
+                <channelDensity id="pasChans" ionChannel="pas" condDensity="3.0 S_per_m2" erev="-70mV" ion="non_specific"/> 
+                <channelDensity id="naChansSoma" ionChannel="NaConductance" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" erev="50mV" ion="na"/>
+                <specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+                <specificCapacitance segmentGroup="dendrite_group" value="2.0 uF_per_cm2"/>
+            </membraneProperties>
+            <intracellularProperties>
+                <resistivity value="0.1 kohm_cm"/>  
+            </intracellularProperties>
+        </biophysicalProperties>
+
+
+
<biophysicalProperties id="PyrCellChanDist">
+        <membraneProperties> 
+        
+            
+            <channelDensity id="naChans" ionChannel="HH_Na" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" ion="na" erev="50mV"/>  
+            <!-- Ions present inside the cell. Note: a fixed reversal potential is specified here  
+            <reversalPotential species="na" value="50mV"/>
+            <reversalPotential species="k" value="-77mV"/>-->
+            
+        </membraneProperties>
+        <intracellularProperties>  
+            <resistivity value="0.1 kohm_cm"/>  
+            <!-- REMOVED UNTIL WE CHECK HOW THE USAGE OF LEMS IMPACTS THIS...
+            <biochemistry reactionScheme="InternalCaDynamics"/>  Ref to earlier pathway -->
+        </intracellularProperties>
+    </biophysicalProperties>
+
+
+
<biophysicalProperties id="biophys">
+            <membraneProperties>
+                <channelDensityNonUniform id="nonuniform_na_chans" ionChannel="NaConductance" erev="50mV" ion="na">
+                    <variableParameter parameter="condDensity" segmentGroup="dendrite_group">
+                        <inhomogeneousValue inhomogeneousParameter="dendrite_group_x1" value="5e-7 * exp(-p/200)"/>  
+                    </variableParameter>
+                </channelDensityNonUniform>
+                <specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+            </membraneProperties>
+            <intracellularProperties>
+                <resistivity value="0.1 kohm_cm"/>  
+            </intracellularProperties>
+        </biophysicalProperties>
+
+
+
+
+
+
+

biophysicalProperties2CaPools#

+

The biophysical properties of the cell, including the membraneProperties2CaPools and the intracellularProperties2CaPools for a cell with two Ca pools.

+
+ +
+ +++++ + + + + + + + + + + +

membraneProperties2CaPools

membraneProperties2CaPools

intracellularProperties2CaPools

intracellularProperties2CaPools

+
+ +
+ +++++ + + + + + + +

totSpecCap

specificCapacitance

+
+ +
+
+
Derived Variables

totSpecCap = membraneProperties2CaPools->totSpecCap (exposed as totSpecCap)

+
+
+
+ +
+
<xs:complexType name="BiophysicalProperties2CaPools">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="membraneProperties2CaPools" type="MembraneProperties2CaPools"/>
+        <xs:element name="intracellularProperties2CaPools" type="IntracellularProperties2CaPools" minOccurs="0"/>
+        <xs:element name="extracellularProperties" type="ExtracellularProperties" minOccurs="0"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BiophysicalProperties2CaPools
+
+variable = BiophysicalProperties2CaPools(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    membrane_properties2_ca_pools: 'a MembraneProperties2CaPools (required)' = None,
+    intracellular_properties2_ca_pools: 'a IntracellularProperties2CaPools (optional)' = None,
+    extracellular_properties: 'a ExtracellularProperties (optional)' = None,
+)
+
+
+
+
+
+
+

intracellularProperties#

+

Biophysical properties related to the intracellular space within the cell, such as the resistivity and the list of ionic species present. caConc and caConcExt are explicitly exposed here to facilitate accessing these values from other Components, even though caConcExt is clearly not an intracellular property.

+
+ +
+ +++++ + + + + + + + + + + +

resistivity

resistivity

speciesList

species

+
+ +
+ +++++ + + + + + + + + + + +

caConc

concentration

caConcExt

concentration

+
+ +
+
+
Derived Variables

caConc = speciesList[ion=‘ca’]->concentration(reduce method: add) (exposed as caConc)

+
+

caConcExt = speciesList[ion=‘ca’]->extConcentration(reduce method: add) (exposed as caConcExt)

+
+
+
+ +
+
<xs:complexType name="IntracellularProperties">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:sequence>
+        <xs:element name="species" type="Species" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="resistivity" type="Resistivity" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IntracellularProperties
+
+variable = IntracellularProperties(
+    species: 'list of Species(s) (optional)' = None,
+    resistivities: 'list of Resistivity(s) (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<intracellularProperties>
+                <resistivity value="0.1 kohm_cm"/>  
+            </intracellularProperties>
+
+
+
<intracellularProperties>  
+            <resistivity value="0.1 kohm_cm"/>  
+            <!-- REMOVED UNTIL WE CHECK HOW THE USAGE OF LEMS IMPACTS THIS...
+            <biochemistry reactionScheme="InternalCaDynamics"/>  Ref to earlier pathway -->
+        </intracellularProperties>
+
+
+
<intracellularProperties>
+                <resistivity value="0.1 kohm_cm"/>  
+            </intracellularProperties>
+
+
+
+
+
+
+

intracellularProperties2CaPools#

+

extends intracellularProperties

+

Variant of intracellularProperties with 2 independent Ca pools.

+
+ +
+ +++++ + + + + + + + + + + +

speciesList

species

resistivity

resistivity

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

caConc

(from intracellularProperties)

concentration

caConc2

concentration

caConcExt

(from intracellularProperties)

concentration

caConcExt2

concentration

+
+ +
+
+
Derived Variables

caConc2 = speciesList[ion=‘ca2’]->concentration(reduce method: add) (exposed as caConc2)

+
+

caConcExt2 = speciesList[ion=‘ca2’]->extConcentration(reduce method: add) (exposed as caConcExt2)

+
+

caConc = speciesList[ion=‘ca’]->concentration(reduce method: add) (exposed as caConc)

+
+

caConcExt = speciesList[ion=‘ca’]->extConcentration(reduce method: add) (exposed as caConcExt)

+
+
+
+ +
+
<xs:complexType name="IntracellularProperties2CaPools">
+  <xs:complexContent>
+    <xs:extension base="IntracellularProperties">
+      </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IntracellularProperties2CaPools
+
+variable = IntracellularProperties2CaPools(
+    species: 'list of Species(s) (optional)' = None,
+    resistivities: 'list of Resistivity(s) (optional)' = None,
+)
+
+
+
+
+
+
+

resistivity#

+

The resistivity, or specific axial resistance, of the cytoplasm.

+
+ +
+ +++++ + + + + + + +

value

resistivity

+
+ +
+ ++++ + + + + + +

segmentGroup

+
+ +
+
<xs:complexType name="Resistivity">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="value" type="Nml2Quantity_resistivity" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Resistivity
+
+variable = Resistivity(
+    value: 'a Nml2Quantity_resistivity (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+)
+
+
+
+ +
+
<resistivity value="0.1 kohm_cm"/>
+
+
+
<resistivity value="0.1 kohm_cm"/>
+
+
+
<resistivity value="0.1 kohm_cm"/>
+
+
+
+
+
+
+

concentrationModel#

+

Base for any model of an ion concentration which changes with time. Internal ( concentration ) and external ( extConcentration ) values for the concentration of the ion are given.

+
+ +
+ ++++ + + + + + +

ion

+
+ +
+ +++++ + + + + + + + + + + +

concentration

concentration

extConcentration

concentration

+
+ +
+ +++++ + + + + + + + + + + + + + + +

initialConcentration

concentration

initialExtConcentration

concentration

surfaceArea

area

+
+ +
+
+
State Variables

concentration: concentration  (exposed as concentration)

+
+

extConcentration: concentration  (exposed as extConcentration)

+
+
On Start

concentration = initialConcentration

+
+

extConcentration = initialExtConcentration

+
+
+
+
+
+
+

decayingPoolConcentrationModel#

+

extends concentrationModel

+

Model of an intracellular buffering mechanism for ion ( currently hard Coded to be calcium, due to requirement for iCa ) which has a baseline level restingConc and tends to this value with time course decayConstant. The ion is assumed to occupy a shell inside the membrane of thickness shellThickness..

+
+ +
+ +++++ + + + + + + + + + + + + + + +

decayConstant

time

restingConc

concentration

shellThickness

length

+
+ +
+ +++++ + + + + + + + + + + + + + + +

Faraday = 96485.3C_per_mol

charge_per_mole

AREA_SCALE = 1m2

area

LENGTH_SCALE = 1m

length

+
+ +
+ ++++ + + + + + +

ion

+
+ +
+ +++++ + + + + + + + + + + +

concentration

(from concentrationModel)

concentration

extConcentration

(from concentrationModel)

concentration

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

iCa

current

initialConcentration

(from concentrationModel)

concentration

initialExtConcentration

(from concentrationModel)

concentration

surfaceArea

(from concentrationModel)

area

+
+ +
+
+
State Variables

concentration: concentration  (exposed as concentration)

+
+

extConcentration: concentration  (exposed as extConcentration)

+
+
On Start

concentration = initialConcentration

+
+

extConcentration = initialExtConcentration

+
+
On Conditions

IF concentration < 0 THEN

+
+

   concentration = 0

+
+
Derived Variables

effectiveRadius = LENGTH_SCALE * sqrt(surfaceArea/(AREA_SCALE * (4 * 3.14159)))

+
+

innerRadius = effectiveRadius - shellThickness

+
+

shellVolume = (4 * (effectiveRadius * effectiveRadius * effectiveRadius) * 3.14159 / 3) - (4 * (innerRadius * innerRadius * innerRadius) * 3.14159 / 3)

+
+
Time Derivatives

d concentration /dt = iCa / (2 * Faraday * shellVolume) - ((concentration - restingConc) / decayConstant)

+
+
+
+ +
+
<xs:complexType name="DecayingPoolConcentrationModel">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="restingConc" type="Nml2Quantity_concentration" use="required"/>
+      <xs:attribute name="decayConstant" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="shellThickness" type="Nml2Quantity_length" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import DecayingPoolConcentrationModel
+
+variable = DecayingPoolConcentrationModel(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    resting_conc: 'a Nml2Quantity_concentration (required)' = None,
+    decay_constant: 'a Nml2Quantity_time (required)' = None,
+    shell_thickness: 'a Nml2Quantity_length (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

fixedFactorConcentrationModel#

+

extends concentrationModel

+

Model of buffering of concentration of an ion ( currently hard coded to be calcium, due to requirement for iCa ) which has a baseline level restingConc and tends to this value with time course decayConstant. A fixed factor rho is used to scale the incoming current independently of the size of the compartment to produce a concentration change.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

decayConstant

time

restingConc

concentration

rho

rho_factor

+
+ +
+ ++++ + + + + + +

ion

+
+ +
+ +++++ + + + + + + + + + + +

concentration

(from concentrationModel)

concentration

extConcentration

(from concentrationModel)

concentration

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

iCa

current

initialConcentration

(from concentrationModel)

concentration

initialExtConcentration

(from concentrationModel)

concentration

surfaceArea

area

surfaceArea

(from concentrationModel)

area

+
+ +
+
+
State Variables

concentration: concentration  (exposed as concentration)

+
+

extConcentration: concentration  (exposed as extConcentration)

+
+
On Start

concentration = initialConcentration

+
+

extConcentration = initialExtConcentration

+
+
On Conditions

IF concentration < 0 THEN

+
+

   concentration = 0

+
+
Time Derivatives

d concentration /dt = (iCa/surfaceArea) * rho - ((concentration - restingConc) / decayConstant)

+
+
+
+ +
+
<xs:complexType name="FixedFactorConcentrationModel">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="ion" type="NmlId" use="required">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="restingConc" type="Nml2Quantity_concentration" use="required"/>
+      <xs:attribute name="decayConstant" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="rho" type="Nml2Quantity_rhoFactor" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import FixedFactorConcentrationModel
+
+variable = FixedFactorConcentrationModel(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    ion: 'a NmlId (required)' = None,
+    resting_conc: 'a Nml2Quantity_concentration (required)' = None,
+    decay_constant: 'a Nml2Quantity_time (required)' = None,
+    rho: 'a Nml2Quantity_rhoFactor (required)' = None,
+)
+
+
+
+
+
+
+

fixedFactorConcentrationModelTraub#

+

extends concentrationModel

+

Model of buffering of concentration of an ion ( currently hard coded to be calcium, due to requirement for iCa ) which has a baseline level restingConc and tends to this value with time course 1 / beta. A fixed factor phi is used to scale the incoming current independently of the size of the compartment to produce a concentration change. Not recommended for use in models other than Traub et al. 2005!

+
+ +
+ +++++ + + + + + + + + + + + + + + +

beta

per_time

phi

rho_factor

restingConc

concentration

+
+ +
+ ++++ + + + + + +

species

+
+ +
+ +++++ + + + + + + + + + + +

concentration

(from concentrationModel)

concentration

extConcentration

(from concentrationModel)

concentration

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

iCa

current

initialConcentration

(from concentrationModel)

concentration

initialExtConcentration

(from concentrationModel)

concentration

surfaceArea

area

surfaceArea

(from concentrationModel)

area

+
+ +
+
+
State Variables

concentration: concentration  (exposed as concentration)

+
+

extConcentration: concentration  (exposed as extConcentration)

+
+
On Start

concentration = initialConcentration

+
+

extConcentration = initialExtConcentration

+
+
On Conditions

IF concentration < 0 THEN

+
+

   concentration = 0

+
+
Time Derivatives

d concentration /dt = (iCa/surfaceArea) * 1e-9 * phi - ((concentration - restingConc) * beta)

+
+
+
+
+
+
+

species#

+

Description of a chemical species identified by ion, which has internal, concentration, and external, extConcentration values for its concentration.

+
+ +
+ +++++ + + + + + + + + + + +

initialConcentration

concentration

initialExtConcentration

concentration

+
+ +
+ ++++ + + + + + + + + +

ion

segmentGroup

+
+ +
+ +++++ + + + + + + +

concentrationModel

concentrationModel

+
+ +
+ +++++ + + + + + + + + + + +

concentration

concentration

extConcentration

concentration

+
+ +
+
+
Structure

CHILD INSTANCE: concentrationModel

+
+
Derived Variables

concentration = concentrationModel->concentration (exposed as concentration)

+
+

extConcentration = concentrationModel->extConcentration (exposed as extConcentration)

+
+
+
+ +
+
<xs:complexType name="Species">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:attribute name="concentrationModel" type="NmlId" use="required"/>
+      <xs:attribute name="ion" type="NmlId" use="optional">
+        <xs:annotation>
+        </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="initialConcentration" type="Nml2Quantity_concentration" use="required"/>
+      <xs:attribute name="initialExtConcentration" type="Nml2Quantity_concentration" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Species
+
+variable = Species(
+    id: 'a NmlId (required)' = None,
+    concentration_model: 'a NmlId (required)' = None,
+    ion: 'a NmlId (optional)' = None,
+    initial_concentration: 'a Nml2Quantity_concentration (required)' = None,
+    initial_ext_concentration: 'a Nml2Quantity_concentration (required)' = None,
+    segment_groups: 'a NmlId (optional)' = 'all',
+)
+
+
+
+
+
+
+

cell#

+

extends baseCellMembPot

+

Cell with segments specified in a morphology element along with details on its biophysicalProperties. NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and v of this cell represents the membrane potential in that isopotential segment.

+
+ +
+ ++++ + + + + + +

neuroLexId

+
+ +
+ +++++ + + + + + + + + + + +

morphology

Should only be used if morphology element is outside the cell. This points to the id of the morphology.

morphology

biophysicalProperties

Should only be used if biophysicalProperties element is outside the cell. This points to the id of the biophysicalProperties

biophysicalProperties

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

caConc

concentration

caConcExt

concentration

iCa

current

iChannels

current

iSyn

current

spiking

Dimensionless

surfaceArea

area

totSpecCap

specificCapacitance

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

spiking: Dimensionless  (exposed as spiking)

+
+
On Start

spiking = 0

+
+

v = initMembPot

+
+
On Conditions

IF v > thresh AND spiking < 0.5 THEN

+
+

   spiking = 1

+
+

   EVENT OUT on port: spike

+
+

IF v < thresh THEN

+
+

   spiking = 0

+
+
Derived Variables

initMembPot = biophysicalProperties->membraneProperties->initMembPotential->value

+
+

thresh = biophysicalProperties->membraneProperties->spikeThresh->value

+
+

surfaceArea = morphology->segments[*]->surfaceArea(reduce method: add) (exposed as surfaceArea)

+
+

totSpecCap = biophysicalProperties->totSpecCap (exposed as totSpecCap)

+
+

totCap = totSpecCap * surfaceArea

+
+

iChannels = biophysicalProperties->membraneProperties->totChanCurrent (exposed as iChannels)

+
+

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iCa = biophysicalProperties->membraneProperties->iCa (exposed as iCa)

+
+

caConc = biophysicalProperties->intracellularProperties->caConc (exposed as caConc)

+
+

caConcExt = biophysicalProperties->intracellularProperties->caConcExt (exposed as caConcExt)

+
+
Time Derivatives

d v /dt = (iChannels + iSyn) / totCap

+
+
+
+ +
+
<xs:complexType name="Cell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:sequence>
+        <xs:element name="morphology" type="Morphology" minOccurs="0"/>
+        <xs:element name="biophysicalProperties" type="BiophysicalProperties" minOccurs="0"/>
+      </xs:sequence>
+      <xs:attribute name="morphology" type="NmlId" use="optional">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="biophysicalProperties" type="NmlId" use="optional">
+        <xs:annotation>
+            </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Cell
+
+variable = Cell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    morphology_attr: 'a NmlId (optional)' = None,
+    biophysical_properties_attr: 'a NmlId (optional)' = None,
+    morphology: 'a Morphology (optional)' = None,
+    biophysical_properties: 'a BiophysicalProperties (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<cell id="SpikingCell" metaid="HippoCA1Cell">
+        <notes>A Simple Spiking cell for testing purposes</notes>
+        
+        <annotation>
+            <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/">
+              <rdf:Description rdf:about="HippoCA1Cell">
+                <bqbiol:is>
+                  <rdf:Bag>
+                    
+                    <rdf:li rdf:resource="urn:miriam:neurondb:258"/>
+                  </rdf:Bag>
+                </bqbiol:is>
+              </rdf:Description>
+            </rdf:RDF>
+        </annotation>
+        <morphology id="SpikingCell_morphology">
+            <segment id="0" name="Soma">
+                
+                <proximal x="0" y="0" z="0" diameter="10"/>
+                <distal x="10" y="0" z="0" diameter="10"/>
+            </segment>
+            <segment id="1" name="Dendrite1">
+                <parent segment="0"/>
+                
+                <distal x="20" y="0" z="0" diameter="3"/>
+            </segment>
+            <segment id="2" name="Dendrite2">
+                <parent segment="1"/>
+                <distal x="30" y="0" z="0" diameter="1"/>
+            </segment>
+            <segment id="3" name="Spine1">
+                <parent segment="2" fractionAlong="0.5"/>
+                <proximal x="25" y="0" z="0" diameter="0.1"/>
+                <distal x="25" y="0.2" z="0" diameter="0.1"/>
+            </segment>
+            
+            <segmentGroup id="soma_group" neuroLexId="sao1044911821">     
+                <member segment="0"/>
+            </segmentGroup>
+            <segmentGroup id="dendrite_group" neuroLexId="sao1211023249">    
+                <member segment="1"/>
+                <member segment="2"/>
+                <member segment="3"/>
+            </segmentGroup>
+            <segmentGroup id="spines" neuroLexId="sao1145756102">    
+                <member segment="3"/>
+            </segmentGroup>
+        </morphology>
+        <biophysicalProperties id="bio_cell">
+            <membraneProperties>
+                <channelPopulation id="naChansDend" ionChannel="NaConductance" segment="2" number="120000" erev="50mV" ion="na"/>   
+                <channelDensity id="pasChans" ionChannel="pas" condDensity="3.0 S_per_m2" erev="-70mV" ion="non_specific"/> 
+                <channelDensity id="naChansSoma" ionChannel="NaConductance" segmentGroup="soma_group" condDensity="120.0 mS_per_cm2" erev="50mV" ion="na"/>
+                <specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+                <specificCapacitance segmentGroup="dendrite_group" value="2.0 uF_per_cm2"/>
+            </membraneProperties>
+            <intracellularProperties>
+                <resistivity value="0.1 kohm_cm"/>  
+            </intracellularProperties>
+        </biophysicalProperties>
+    </cell>
+
+
+
<cell id="PyrCell" morphology="NeuroMorpho_PyrCell123" biophysicalProperties="PyrCellChanDist"/>
+
+
+
<cell id="SimpleCell">
+        <morphology id="SimpleCell_Morphology">
+            
+            <segment id="0" name="Soma">    
+                
+                <proximal x="0" y="0" z="0" diameter="10"/>
+                <distal x="10" y="0" z="0" diameter="10"/>
+            </segment>
+            <segment id="1" name="MainDendrite1">
+                <parent segment="0"/>
+                
+                <proximal x="10" y="0" z="0" diameter="3"/> 
+                <distal x="20" y="0" z="0" diameter="3"/>
+            </segment>
+            <segment id="2" name="MainDendrite2">
+                <parent segment="1"/>
+                
+                <distal x="30" y="0" z="0" diameter="1"/>
+            </segment>
+            
+            <segmentGroup id="soma_group" neuroLexId="sao1044911821">    
+                <member segment="0"/>
+            </segmentGroup>
+            <segmentGroup id="dendrite_group" neuroLexId="sao1211023249">
+                <member segment="1"/>
+                <member segment="2"/>
+                
+                <inhomogeneousParameter id="dendrite_group_x1" variable="p" metric="Path Length from root"/>
+ 
+                <inhomogeneousParameter id="dendrite_group_x2" variable="r" metric="Path Length from root">
+                        <proximal translationStart="0"/>
+                        <distal normalizationEnd="1"/>
+                </inhomogeneousParameter>
+                
+            </segmentGroup>
+        </morphology>
+        
+        <biophysicalProperties id="biophys">
+            <membraneProperties>
+                <channelDensityNonUniform id="nonuniform_na_chans" ionChannel="NaConductance" erev="50mV" ion="na">
+                    <variableParameter parameter="condDensity" segmentGroup="dendrite_group">
+                        <inhomogeneousValue inhomogeneousParameter="dendrite_group_x1" value="5e-7 * exp(-p/200)"/>  
+                    </variableParameter>
+                </channelDensityNonUniform>
+                <specificCapacitance segmentGroup="soma_group" value="1.0 uF_per_cm2"/>
+            </membraneProperties>
+            <intracellularProperties>
+                <resistivity value="0.1 kohm_cm"/>  
+            </intracellularProperties>
+        </biophysicalProperties>
+    </cell>
+
+
+
+
+
+
+

cell2CaPools#

+

extends cell

+

Variant of cell with two independent Ca2+ pools. Cell with segments specified in a morphology element along with details on its biophysicalProperties. NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and v of this cell represents the membrane potential in that isopotential segment.

+
+ +
+ ++++ + + + + + +

neuroLexId

+
+ +
+ +++++ + + + + + + +

biophysicalProperties2CaPools

biophysicalProperties2CaPools

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

caConc

(from cell)

concentration

caConc2

concentration

caConcExt

(from cell)

concentration

caConcExt2

concentration

iCa

(from cell)

current

iCa2

current

iChannels

(from cell)

current

iSyn

(from cell)

current

spiking

(from cell)

Dimensionless

surfaceArea

(from cell)

area

totSpecCap

(from cell)

specificCapacitance

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

spiking: Dimensionless  (exposed as spiking)

+
+
On Start

spiking = 0

+
+

v = initMembPot

+
+
On Conditions

IF v > thresh AND spiking < 0.5 THEN

+
+

   spiking = 1

+
+

   EVENT OUT on port: spike

+
+

IF v < thresh THEN

+
+

   spiking = 0

+
+
Derived Variables

initMembPot = biophysicalProperties2CaPools->membraneProperties2CaPools->initMembPotential->value

+
+

thresh = biophysicalProperties2CaPools->membraneProperties2CaPools->spikeThresh->value

+
+

surfaceArea = morphology->segments[*]->surfaceArea(reduce method: add) (exposed as surfaceArea)

+
+

totSpecCap = biophysicalProperties2CaPools->totSpecCap (exposed as totSpecCap)

+
+

totCap = totSpecCap * surfaceArea

+
+

iChannels = biophysicalProperties2CaPools->membraneProperties2CaPools->totChanCurrent (exposed as iChannels)

+
+

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iCa = biophysicalProperties2CaPools->membraneProperties2CaPools->iCa (exposed as iCa)

+
+

caConc = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConc (exposed as caConc)

+
+

caConcExt = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConcExt (exposed as caConcExt)

+
+

iCa2 = biophysicalProperties2CaPools->membraneProperties2CaPools->iCa2 (exposed as iCa2)

+
+

caConc2 = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConc2 (exposed as caConc2)

+
+

caConcExt2 = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConcExt2 (exposed as caConcExt2)

+
+
Time Derivatives

d v /dt = (iChannels + iSyn) / totCap

+
+
+
+ +
+
<xs:complexType name="Cell2CaPools">
+  <xs:complexContent>
+    <xs:extension base="Cell">
+      <xs:sequence>
+        <xs:element name="biophysicalProperties2CaPools" type="BiophysicalProperties2CaPools" minOccurs="0"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Cell2CaPools
+
+variable = Cell2CaPools(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    morphology_attr: 'a NmlId (optional)' = None,
+    biophysical_properties_attr: 'a NmlId (optional)' = None,
+    morphology: 'a Morphology (optional)' = None,
+    biophysical_properties: 'a BiophysicalProperties (optional)' = None,
+    biophysical_properties2_ca_pools: 'a BiophysicalProperties2CaPools (optional)' = None,
+)
+
+
+
+
+
+
+

baseCellMembPotCap#

+

extends baseCellMembPot

+

Any cell with a membrane potential v with voltage units and a membrane capacitance C. Also defines exposed value iSyn for current due to external synapses and iMemb for total transmembrane current ( usually channel currents plus iSyn ).

+
+ +
+ +++++ + + + + + + +

C

Total capacitance of the cell membrane

capacitance

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane

current

iSyn

Total current due to synaptic inputs

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+
<xs:complexType name="BaseCellMembPotCap">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="C" type="Nml2Quantity_capacitance" use="required">
+        <xs:annotation>
+          <xs:appinfo>
+            <jxb:property name="Cap"/>
+          </xs:appinfo>
+        </xs:annotation>
+      </xs:attribute>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseCellMembPotCap
+
+variable = BaseCellMembPotCap(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    C: 'a Nml2Quantity_capacitance (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

baseIaf#

+

extends baseCellMembPot

+

Base ComponentType for an integrate and fire cell which emits a spiking event at membrane potential thresh and and resets to reset.

+
+ +
+ +++++ + + + + + + + + + + +

reset

The value the membrane potential is reset to on spiking

voltage

thresh

The membrane potential at which to emit a spiking event and reset voltage

voltage

+
+ +
+ +++++ + + + + + + +

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+
+
+
+

iafTauCell#

+

extends baseIaf

+

Integrate and fire cell which returns to its leak reversal potential of leakReversal with a time constant tau.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

leakReversal

voltage

reset

The value the membrane potential is reset to on spiking (from baseIaf)

voltage

tau

time

thresh

The membrane potential at which to emit a spiking event and reset voltage (from baseIaf)

voltage

+
+ +
+ +++++ + + + + + + +

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+
On Start

v = leakReversal

+
+
On Conditions

IF v > thresh THEN

+
+

   v = reset

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d v /dt = (leakReversal - v) / tau

+
+
+
+ +
+
<xs:complexType name="IafTauCell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="leakReversal" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="thresh" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="reset" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="tau" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IafTauCell
+
+variable = IafTauCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    leak_reversal: 'a Nml2Quantity_voltage (required)' = None,
+    thresh: 'a Nml2Quantity_voltage (required)' = None,
+    reset: 'a Nml2Quantity_voltage (required)' = None,
+    tau: 'a Nml2Quantity_time (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<iafTauCell id="iafTau" leakReversal="-50mV" thresh="-55mV" reset="-70mV" tau="30ms"/>
+
+
+
+
+
+
+

iafTauRefCell#

+

extends iafTauCell

+

Integrate and fire cell which returns to its leak reversal potential of leakReversal with a time course tau. It has a refractory period of refract after spiking.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

leakReversal

(from iafTauCell)

voltage

refract

time

reset

The value the membrane potential is reset to on spiking (from baseIaf)

voltage

tau

(from iafTauCell)

time

thresh

The membrane potential at which to emit a spiking event and reset voltage (from baseIaf)

voltage

+
+ +
+ +++++ + + + + + + +

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

lastSpikeTime: time

+
+
On Start

v = leakReversal

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = reset

+
+

On Conditions

+
+

   IF t > lastSpikeTime + refract THEN

+
+

    TRANSITION to REGIME integrating

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > thresh THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (leakReversal - v) / tau

+
+
+
+ +
+
<xs:complexType name="IafTauRefCell">
+  <xs:complexContent>
+    <xs:extension base="IafTauCell">
+      <xs:attribute name="refract" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IafTauRefCell
+
+variable = IafTauRefCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    leak_reversal: 'a Nml2Quantity_voltage (required)' = None,
+    thresh: 'a Nml2Quantity_voltage (required)' = None,
+    reset: 'a Nml2Quantity_voltage (required)' = None,
+    tau: 'a Nml2Quantity_time (required)' = None,
+    refract: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<iafTauRefCell id="iafTauRef" leakReversal="-50mV" thresh="-55mV" reset="-70mV" tau="30ms" refract="5ms"/>
+
+
+
+
+
+
+

baseIafCapCell#

+

extends baseCellMembPotCap

+

Base Type for all Integrate and Fire cells with a capacitance C, threshold thresh and reset membrane potential reset.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

reset

voltage

thresh

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+
+
+
+

iafCell#

+

extends baseIafCapCell

+

Integrate and fire cell with capacitance C, leakConductance and leakReversal.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

leakConductance

conductance

leakReversal

voltage

reset

(from baseIafCapCell)

voltage

thresh

(from baseIafCapCell)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+
On Start

v = leakReversal

+
+
On Conditions

IF v > thresh THEN

+
+

   v = reset

+
+

   EVENT OUT on port: spike

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iMemb = leakConductance * (leakReversal - v) + iSyn (exposed as iMemb)

+
+
Time Derivatives

d v /dt = iMemb / C

+
+
+
+ +
+
<xs:complexType name="IafCell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="leakReversal" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="thresh" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="reset" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="C" type="Nml2Quantity_capacitance" use="required"/>
+      <xs:attribute name="leakConductance" type="Nml2Quantity_conductance" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IafCell
+
+variable = IafCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    leak_reversal: 'a Nml2Quantity_voltage (required)' = None,
+    thresh: 'a Nml2Quantity_voltage (required)' = None,
+    reset: 'a Nml2Quantity_voltage (required)' = None,
+    C: 'a Nml2Quantity_capacitance (required)' = None,
+    leak_conductance: 'a Nml2Quantity_conductance (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<iafCell id="iaf" leakReversal="-50mV" thresh="-55mV" reset="-70mV" C="0.2nF" leakConductance="0.01uS"/>
+
+
+
<iafCell id="iaf" leakConductance="0.2nS" leakReversal="-70mV" thresh="-55mV" reset="-70mV" C="3.2pF"/>
+
+
+
<iafCell id="iaf" leakConductance="0.2nS" leakReversal="-70mV" thresh="-55mV" reset="-70mV" C="3.2pF"/>
+
+
+
+
+
+
+

iafRefCell#

+

extends iafCell

+

Integrate and fire cell with capacitance C, leakConductance, leakReversal and refractory period refract.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

leakConductance

(from iafCell)

conductance

leakReversal

(from iafCell)

voltage

refract

time

reset

(from baseIafCapCell)

voltage

thresh

(from baseIafCapCell)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

lastSpikeTime: time

+
+
On Start

v = leakReversal

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iMemb = leakConductance * (leakReversal - v) + iSyn (exposed as iMemb)

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = reset

+
+

On Conditions

+
+

   IF t > lastSpikeTime + refract THEN

+
+

    TRANSITION to REGIME integrating

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > thresh THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = iMemb / C

+
+
+
+ +
+
<xs:complexType name="IafRefCell">
+  <xs:complexContent>
+    <xs:extension base="IafCell">
+      <xs:attribute name="refract" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IafRefCell
+
+variable = IafRefCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    leak_reversal: 'a Nml2Quantity_voltage (required)' = None,
+    thresh: 'a Nml2Quantity_voltage (required)' = None,
+    reset: 'a Nml2Quantity_voltage (required)' = None,
+    C: 'a Nml2Quantity_capacitance (required)' = None,
+    leak_conductance: 'a Nml2Quantity_conductance (required)' = None,
+    refract: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<iafRefCell id="iafRef" leakReversal="-50mV" thresh="-55mV" reset="-70mV" C="0.2nF" leakConductance="0.01uS" refract="5ms"/>
+
+
+
+
+
+
+

izhikevichCell#

+

extends baseCellMembPot

+

Cell based on the 2003 model of Izhikevich, see http://izhikevich.org/publications/spikes.htm.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

a

Time scale of the recovery variable U

Dimensionless

b

Sensitivity of U to the subthreshold fluctuations of the membrane potential V

Dimensionless

c

After-spike reset value of V

Dimensionless

d

After-spike increase to U

Dimensionless

thresh

Spike threshold

voltage

v0

Initial membrane potential

voltage

+
+ +
+ +++++ + + + + + + + + + + +

MSEC = 1ms

time

MVOLT = 1mV

voltage

+
+ +
+ +++++ + + + + + + + + + + +

U

Membrane recovery variable

Dimensionless

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrentDL

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

U: Dimensionless  (exposed as U)

+
+
On Start

v = v0

+
+

U = v0 * b / MVOLT

+
+
On Conditions

IF v > thresh THEN

+
+

   v = c * MVOLT

+
+

   U = U + d

+
+

   EVENT OUT on port: spike

+
+
Derived Variables

ISyn = synapses[*]->I(reduce method: add)

+
+
Time Derivatives

d v /dt = (0.04 * v^2 / MVOLT + 5 * v + (140.0 - U + ISyn) * MVOLT)/MSEC

+
+

d U /dt = a * (b * v / MVOLT - U) / MSEC

+
+
+
+ +
+
<xs:complexType name="IzhikevichCell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="v0" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="thresh" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="a" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="b" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="c" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="d" type="Nml2Quantity_none" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IzhikevichCell
+
+variable = IzhikevichCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    v0: 'a Nml2Quantity_voltage (required)' = None,
+    thresh: 'a Nml2Quantity_voltage (required)' = None,
+    a: 'a Nml2Quantity_none (required)' = None,
+    b: 'a Nml2Quantity_none (required)' = None,
+    c: 'a Nml2Quantity_none (required)' = None,
+    d: 'a Nml2Quantity_none (required)' = None,
+)
+
+
+
+ +
+
<izhikevichCell id="izBurst" v0="-70mV" thresh="30mV" a="0.02" b="0.2" c="-50.0" d="2"/>
+
+
+
+
+
+
+

izhikevich2007Cell#

+

extends baseCellMembPotCap

+

Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

a

Time scale of recovery variable u

per_time

b

Sensitivity of recovery variable u to subthreshold fluctuations of membrane potential v

conductance

c

After-spike reset value of v

voltage

d

After-spike increase to u

current

k

conductance_per_voltage

v0

Initial membrane potential

voltage

vpeak

Peak action potential value

voltage

vr

Resting membrane potential

voltage

vt

Spike threshold

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

u

Membrane recovery variable

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

u: current  (exposed as u)

+
+
On Start

v = v0

+
+

u = 0

+
+
On Conditions

IF v > vpeak THEN

+
+

   v = c

+
+

   u = u + d

+
+

   EVENT OUT on port: spike

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iMemb = k * (v-vr) * (v-vt) + iSyn - u (exposed as iMemb)

+
+
Time Derivatives

d v /dt = iMemb / C

+
+

d u /dt = a * (b * (v-vr) - u)

+
+
+
+ +
+
<xs:complexType name="Izhikevich2007Cell">
+  <xs:complexContent>
+    <xs:extension base="BaseCellMembPotCap">
+      <xs:attribute name="v0" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="k" type="Nml2Quantity_conductancePerVoltage" use="required"/>
+      <xs:attribute name="vr" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="vt" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="vpeak" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="a" type="Nml2Quantity_pertime" use="required"/>
+      <xs:attribute name="b" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="c" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="d" type="Nml2Quantity_current" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Izhikevich2007Cell
+
+variable = Izhikevich2007Cell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    C: 'a Nml2Quantity_capacitance (required)' = None,
+    v0: 'a Nml2Quantity_voltage (required)' = None,
+    k: 'a Nml2Quantity_conductancePerVoltage (required)' = None,
+    vr: 'a Nml2Quantity_voltage (required)' = None,
+    vt: 'a Nml2Quantity_voltage (required)' = None,
+    vpeak: 'a Nml2Quantity_voltage (required)' = None,
+    a: 'a Nml2Quantity_pertime (required)' = None,
+    b: 'a Nml2Quantity_conductance (required)' = None,
+    c: 'a Nml2Quantity_voltage (required)' = None,
+    d: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+ +
+
<izhikevich2007Cell id="iz2007RS" v0="-60mV" C="100 pF" k="0.7 nS_per_mV" vr="-60 mV" vt="-40 mV" vpeak="35 mV" a="0.03 per_ms" b="-2 nS" c="-50 mV" d="100 pA"/>
+
+
+
+
+
+
+

adExIaFCell#

+

extends baseCellMembPotCap

+

Model based on Brette R and Gerstner W ( 2005 ) Adaptive Exponential Integrate-and-Fire Model as an Effective Description of Neuronal Activity. J Neurophysiol 94:3637-3642.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

EL

Leak reversal potential

voltage

VT

Spike threshold

voltage

a

Sub-threshold adaptation variable

conductance

b

Spike-triggered adaptation variable

current

delT

Slope factor

voltage

gL

Leak conductance

conductance

refract

Refractory period

time

reset

Reset potential

voltage

tauw

Adaptation time constant

time

thresh

Spike detection threshold

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

v

Membrane potential (from baseCellMembPot)

voltage

w

Adaptation current

current

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

w: current  (exposed as w)

+
+

lastSpikeTime: time

+
+
On Start

v = EL

+
+

w = 0

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iMemb = -1 * gL * (v - EL) + gL * delT * exp((v - VT) / delT) - w + iSyn (exposed as iMemb)

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = reset

+
+

   w = w + b

+
+

On Conditions

+
+

   IF t > lastSpikeTime + refract THEN

+
+

    TRANSITION to REGIME integrating

+
+

Time Derivatives

+
+

   d w /dt = (a * (v - EL) - w) / tauw

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > thresh THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = iMemb / C

+
+

   d w /dt = (a * (v - EL) - w) / tauw

+
+
+
+ +
+
<xs:complexType name="AdExIaFCell">
+  <xs:complexContent>
+    <xs:extension base="BaseCellMembPotCap">
+      <xs:attribute name="gL" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="EL" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="reset" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="VT" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="thresh" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="delT" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="tauw" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="refract" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="a" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="b" type="Nml2Quantity_current" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import AdExIaFCell
+
+variable = AdExIaFCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    C: 'a Nml2Quantity_capacitance (required)' = None,
+    g_l: 'a Nml2Quantity_conductance (required)' = None,
+    EL: 'a Nml2Quantity_voltage (required)' = None,
+    reset: 'a Nml2Quantity_voltage (required)' = None,
+    VT: 'a Nml2Quantity_voltage (required)' = None,
+    thresh: 'a Nml2Quantity_voltage (required)' = None,
+    del_t: 'a Nml2Quantity_voltage (required)' = None,
+    tauw: 'a Nml2Quantity_time (required)' = None,
+    refract: 'a Nml2Quantity_time (required)' = None,
+    a: 'a Nml2Quantity_conductance (required)' = None,
+    b: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+ +
+
<adExIaFCell id="adExBurst" C="281pF" gL="30nS" EL="-70.6mV" reset="-48.5mV" VT="-50.4mV" thresh="-40.4mV" refract="0ms" delT="2mV" tauw="40ms" a="4nS" b="0.08nA"/>
+
+
+
+
+
+
+

fitzHughNagumoCell#

+

extends baseCellMembPotDL

+

Simple dimensionless model of spiking cell from FitzHugh and Nagumo. Superseded by fitzHughNagumo1969Cell ( See NeuroML/NeuroML2#42 ).

+
+ +
+ +++++ + + + + + + +

I

Dimensionless

+
+ +
+ +++++ + + + + + + +

SEC = 1s

time

+
+ +
+ +++++ + + + + + + + + + + +

V

Membrane potential (from baseCellMembPotDL)

Dimensionless

W

Dimensionless

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+
+
State Variables

V: Dimensionless  (exposed as V)

+
+

W: Dimensionless  (exposed as W)

+
+
Time Derivatives

d V /dt = ( (V - ((V^3) / 3)) - W + I) / SEC

+
+

d W /dt = (0.08 * (V + 0.7 - 0.8 * W)) / SEC

+
+
+
+ +
+
<xs:complexType name="FitzHughNagumoCell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="I" type="Nml2Quantity_none" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import FitzHughNagumoCell
+
+variable = FitzHughNagumoCell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    I: 'a Nml2Quantity_none (required)' = None,
+)
+
+
+
+ +
+
<fitzHughNagumoCell id="fn1" I="0.8"/>
+
+
+
+
+
+
+

pinskyRinzelCA3Cell#

+

extends baseCellMembPot

+

Reduced CA3 cell model from Pinsky, P.F., Rinzel, J. Intrinsic and network rhythmogenesis in a reduced traub model for CA3 neurons. J Comput Neurosci 1, 39-60 ( 1994 ). See OpenSourceBrain/PinskyRinzelModel.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

alphac

Dimensionless

betac

Dimensionless

cm

specificCapacitance

eCa

voltage

eK

voltage

eL

voltage

eNa

voltage

gAmpa

conductanceDensity

gCa

conductanceDensity

gKC

conductanceDensity

gKahp

conductanceDensity

gKdr

conductanceDensity

gLd

conductanceDensity

gLs

conductanceDensity

gNa

conductanceDensity

gNmda

conductanceDensity

gc

conductanceDensity

iDend

currentDensity

iSoma

currentDensity

pp

Dimensionless

qd0

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

MSEC = 1 ms

time

MVOLT = 1 mV

voltage

UAMP_PER_CM2 = 1 uA_per_cm2

currentDensity

Smax = 125.0

Dimensionless

Vsyn = 60.0 mV

voltage

betaqd = 0.001

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Cad

Dimensionless

ICad

currentDensity

Si

Dimensionless

Vd

Dendritic membrane potential

voltage

Vs

Somatic membrane potential

voltage

Wi

Dimensionless

cd

Dimensionless

hs

Dimensionless

ns

Dimensionless

qd

Dimensionless

sd

Dimensionless

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+
+
State Variables

Vs: voltage  (exposed as Vs)

+
+

Vd: voltage  (exposed as Vd)

+
+

Cad: Dimensionless  (exposed as Cad)

+
+

hs: Dimensionless  (exposed as hs)

+
+

ns: Dimensionless  (exposed as ns)

+
+

sd: Dimensionless  (exposed as sd)

+
+

cd: Dimensionless  (exposed as cd)

+
+

qd: Dimensionless  (exposed as qd)

+
+

Si: Dimensionless  (exposed as Si)

+
+

Wi: Dimensionless  (exposed as Wi)

+
+

Sisat: Dimensionless

+
+
On Start

Vs = eL

+
+

Vd = eL

+
+

qd = qd0

+
+
Derived Variables

v = Vs (exposed as v)

+
+

ICad = gCasdsd*(Vd-eCa) (exposed as ICad)

+
+

alphams_Vs = 0.32*(-46.9-Vs/MVOLT)/(exp((-46.9-Vs/MVOLT)/4.0)-1.0)

+
+

betams_Vs = 0.28*(Vs/MVOLT+19.9)/(exp((Vs/MVOLT+19.9)/5.0)-1.0)

+
+

Minfs_Vs = alphams_Vs/(alphams_Vs+betams_Vs)

+
+

alphans_Vs = 0.016*(-24.9-Vs/MVOLT)/(exp((-24.9-Vs/MVOLT)/5.0)-1.0)

+
+

betans_Vs = 0.25exp(-1.0-0.025Vs/MVOLT)

+
+

alphahs_Vs = 0.128*exp((-43.0-Vs/MVOLT)/18.0)

+
+

betahs_Vs = 4.0/(1.0+exp((-20.0-Vs/MVOLT)/5.0))

+
+

alphasd_Vd = 1.6/(1.0+exp(-0.072*(Vd/MVOLT-5.0)))

+
+

betasd_Vd = 0.02*(Vd/MVOLT+8.9)/(exp((Vd/MVOLT+8.9)/5.0)-1.0)

+
+

Iampa = gAmpaWi(Vd-Vsyn)

+
+

Inmda = gNmdaSisat(Vd-Vsyn)/(1.0+0.28exp(-0.062(Vd/MVOLT-60.0)))

+
+

Isyn = Iampa+Inmda

+
+
Conditional Derived Variables

IF 0.00002*Cad > 0.01 THEN

+
+

alphaqd = 0.01

+
+

OTHERWISE

+
+

alphaqd = 0.00002*Cad

+
+

IF Cad/250 > 1 THEN

+
+

chid = 1

+
+

OTHERWISE

+
+

chid = Cad/250

+
+

IF Vd < -10*MVOLT THEN

+
+

alphacd_Vd = exp((Vd/MVOLT+50.0)/11-(Vd/MVOLT+53.5)/27)/18.975

+
+

OTHERWISE

+
+

alphacd_Vd = 2.0*exp((-53.5-Vd/MVOLT)/27.0)

+
+

IF Vd < -10*MVOLT THEN

+
+

betacd_Vd = (2.0*exp((-53.5-Vd/MVOLT)/27.0)-alphacd_Vd)

+
+

OTHERWISE

+
+

betacd_Vd = 0

+
+

IF Si > Smax THEN

+
+

Sisat = Smax

+
+

OTHERWISE

+
+

Sisat = Si

+
+
Time Derivatives

d Vs /dt = (-gLs*(Vs-eL)-gNa*(Minfs_Vs^2)hs(Vs-eNa)-gKdrns(Vs-eK)+(gc/pp)*(Vd-Vs)+iSoma/pp) / cm

+
+

d Vd /dt = (iDend/(1.0-pp)-Isyn/(1.0-pp)-gLd*(Vd-eL)-ICad-gKahpqd(Vd-eK)-gKCcdchid*(Vd-eK)+(gc*(Vs-Vd))/(1.0-pp)) / cm

+
+

d Cad /dt = (-0.13ICad/UAMP_PER_CM2-0.075Cad) / MSEC

+
+

d hs /dt = (alphahs_Vs-(alphahs_Vs+betahs_Vs)*hs) / MSEC

+
+

d ns /dt = (alphans_Vs-(alphans_Vs+betans_Vs)*ns) / MSEC

+
+

d sd /dt = (alphasd_Vd-(alphasd_Vd+betasd_Vd)*sd) / MSEC

+
+

d cd /dt = (alphacd_Vd-(alphacd_Vd+betacd_Vd)*cd) / MSEC

+
+

d qd /dt = (alphaqd-(alphaqd+betaqd)*qd) / MSEC

+
+

d Si /dt = -Si/150.0

+
+

d Wi /dt = -Wi/2.0

+
+
+
+ +
+
<xs:complexType name="PinskyRinzelCA3Cell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="iSoma" type="Nml2Quantity_currentDensity" use="required"/>
+      <xs:attribute name="iDend" type="Nml2Quantity_currentDensity" use="required"/>
+      <xs:attribute name="gc" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gLs" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gLd" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gNa" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gKdr" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gCa" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gKahp" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gKC" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gNmda" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="gAmpa" type="Nml2Quantity_conductanceDensity" use="required"/>
+      <xs:attribute name="eNa" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="eCa" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="eK" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="eL" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="qd0" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="pp" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="alphac" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="betac" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="cm" type="Nml2Quantity_specificCapacitance" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import PinskyRinzelCA3Cell
+
+variable = PinskyRinzelCA3Cell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    i_soma: 'a Nml2Quantity_currentDensity (required)' = None,
+    i_dend: 'a Nml2Quantity_currentDensity (required)' = None,
+    gc: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_ls: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_ld: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_na: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_kdr: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_ca: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_kahp: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_kc: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_nmda: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    g_ampa: 'a Nml2Quantity_conductanceDensity (required)' = None,
+    e_na: 'a Nml2Quantity_voltage (required)' = None,
+    e_ca: 'a Nml2Quantity_voltage (required)' = None,
+    e_k: 'a Nml2Quantity_voltage (required)' = None,
+    e_l: 'a Nml2Quantity_voltage (required)' = None,
+    qd0: 'a Nml2Quantity_none (required)' = None,
+    pp: 'a Nml2Quantity_none (required)' = None,
+    alphac: 'a Nml2Quantity_none (required)' = None,
+    betac: 'a Nml2Quantity_none (required)' = None,
+    cm: 'a Nml2Quantity_specificCapacitance (required)' = None,
+)
+
+
+
+ +
+
<pinskyRinzelCA3Cell id="pr2A" iSoma="0.75 uA_per_cm2" iDend="0 uA_per_cm2" gc="2.1 mS_per_cm2" qd0="0" gLs="0.1 mS_per_cm2" gLd="0.1 mS_per_cm2" gNa="30 mS_per_cm2" gKdr="15 mS_per_cm2" gCa="10 mS_per_cm2" gKahp="0.8 mS_per_cm2" gKC="15 mS_per_cm2" eNa="60 mV" eCa="80 mV" eK="-75 mV" eL="-60 mV" pp="0.5" cm="3 uF_per_cm2" alphac="2" betac="0.1" gNmda="0 mS_per_cm2" gAmpa="0 mS_per_cm2"/>
+
+
+
+
+
+
+

hindmarshRose1984Cell#

+

extends baseCellMembPotCap

+

The Hindmarsh Rose model is a simplified point cell model which captures complex firing patterns of single neurons, such as periodic and chaotic bursting. It has a fast spiking subsystem, which is a generalization of the FitzHugh-Nagumo system, coupled to a slower subsystem which allows the model to fire bursts. The dynamical variables x, y, z correspond to the membrane potential, a recovery variable, and a slower adaptation current, respectively. See Hindmarsh J. L., and Rose R. M. ( 1984 ) A model of neuronal bursting using three coupled first order differential equations. Proc. R. Soc. London, Ser. B 221:87–102.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

C

Total capacitance of the cell membrane (from baseCellMembPotCap)

capacitance

a

cubic term in x nullcline

Dimensionless

b

quadratic term in x nullcline

Dimensionless

c

constant term in y nullcline

Dimensionless

d

quadratic term in y nullcline

Dimensionless

r

timescale separation between slow and fast subsystem (r greater than 0; r much less than 1)

Dimensionless

s

related to adaptation

Dimensionless

v_scaling

scaling of x for physiological membrane potential

voltage

x0

Dimensionless

x1

related to the system’s resting potential

Dimensionless

y0

Dimensionless

z0

Dimensionless

+
+ +
+ +++++ + + + + + + +

MSEC = 1ms

time

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

chi

Dimensionless

iMemb

Total current crossing the cell membrane (from baseCellMembPotCap)

current

iSyn

Total current due to synaptic inputs (from baseCellMembPotCap)

current

phi

Dimensionless

rho

Dimensionless

spiking

Dimensionless

v

Membrane potential (from baseCellMembPot)

voltage

x

Dimensionless

y

Dimensionless

z

Dimensionless

+
+ +
+ +++++ + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

+
+ +
+ +++++ + + + + + + +

synapses

basePointCurrent

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

y: Dimensionless  (exposed as y)

+
+

z: Dimensionless  (exposed as z)

+
+

spiking: Dimensionless  (exposed as spiking)

+
+
On Start

v = x0 * v_scaling

+
+

y = y0

+
+

z = z0

+
+
On Conditions

IF v > 0 AND spiking < 0.5 THEN

+
+

   spiking = 1

+
+

   EVENT OUT on port: spike

+
+

IF v < 0 THEN

+
+

   spiking = 0

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

x = v / v_scaling (exposed as x)

+
+

phi = y - a * x^3 + b * x^2 (exposed as phi)

+
+

chi = c - d * x^2 - y (exposed as chi)

+
+

rho = s * ( x - x1 ) - z (exposed as rho)

+
+

iMemb = (C * (v_scaling * (phi - z) / MSEC)) + iSyn (exposed as iMemb)

+
+
Time Derivatives

d v /dt = iMemb/C

+
+

d y /dt = chi / MSEC

+
+

d z /dt = r * rho / MSEC

+
+
+
+ +
+
<xs:complexType name="HindmarshRose1984Cell">
+  <xs:complexContent>
+    <xs:extension base="BaseCellMembPotCap">
+      <xs:attribute name="a" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="b" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="c" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="d" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="s" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="x1" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="r" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="x0" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="y0" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="z0" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="v_scaling" type="Nml2Quantity_voltage" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import HindmarshRose1984Cell
+
+variable = HindmarshRose1984Cell(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    C: 'a Nml2Quantity_capacitance (required)' = None,
+    a: 'a Nml2Quantity_none (required)' = None,
+    b: 'a Nml2Quantity_none (required)' = None,
+    c: 'a Nml2Quantity_none (required)' = None,
+    d: 'a Nml2Quantity_none (required)' = None,
+    s: 'a Nml2Quantity_none (required)' = None,
+    x1: 'a Nml2Quantity_none (required)' = None,
+    r: 'a Nml2Quantity_none (required)' = None,
+    x0: 'a Nml2Quantity_none (required)' = None,
+    y0: 'a Nml2Quantity_none (required)' = None,
+    z0: 'a Nml2Quantity_none (required)' = None,
+    v_scaling: 'a Nml2Quantity_voltage (required)' = None,
+)
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Channels.html b/Userdocs/Schemas/Channels.html new file mode 100644 index 00000000..07b21897 --- /dev/null +++ b/Userdocs/Schemas/Channels.html @@ -0,0 +1,4842 @@ + + + + + + + + + + + Channels — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Channels#

+

Defines voltage ( and concentration ) gated ion channel models. Ion channels will generally extend baseIonChannel. The most commonly used voltage dependent gate will extend baseGate.

+
+

Original ComponentType definitions: Channels.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

baseVoltageDepRate#

+

Base ComponentType for voltage dependent rate. Produces a time varying rate r which depends on v..

+
+ +
+ +++++ + + + + + + +

r

per_time

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+
+
+
+

baseVoltageConcDepRate#

+

extends baseVoltageDepRate

+

Base ComponentType for voltage and concentration dependent rate. Produces a time varying rate r which depends on v and caConc..

+
+ +
+ +++++ + + + + + + +

r

(from baseVoltageDepRate)

per_time

+
+ +
+ +++++ + + + + + + + + + + +

caConc

concentration

v

(from baseVoltageDepRate)

voltage

+
+
+
+
+

baseHHRate#

+

extends baseVoltageDepRate

+

Base ComponentType for rate which follow one of the typical forms for rate equations in the standard HH formalism, using the parameters rate, midpoint and scale.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

voltage

rate

per_time

scale

voltage

+
+ +
+ +++++ + + + + + + +

r

(from baseVoltageDepRate)

per_time

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepRate)

voltage

+
+
+
+
+

HHExpRate#

+

extends baseHHRate

+

Exponential form for rate equation ( Q: Should these be renamed hhExpRate, etc? ).

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

(from baseHHRate)

voltage

rate

(from baseHHRate)

per_time

scale

(from baseHHRate)

voltage

+
+ +
+ +++++ + + + + + + +

r

(from baseVoltageDepRate)

per_time

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepRate)

voltage

+
+ +
+
+
Derived Variables

r = rate * exp((v - midpoint)/scale) (exposed as r)

+
+
+
+
+
+
+

HHSigmoidRate#

+

extends baseHHRate

+

Sigmoidal form for rate equation.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

(from baseHHRate)

voltage

rate

(from baseHHRate)

per_time

scale

(from baseHHRate)

voltage

+
+ +
+ +++++ + + + + + + +

r

(from baseVoltageDepRate)

per_time

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepRate)

voltage

+
+ +
+
+
Derived Variables

r = rate / (1 + exp(0 - (v - midpoint)/scale)) (exposed as r)

+
+
+
+
+
+
+

HHExpLinearRate#

+

extends baseHHRate

+

Exponential linear form for rate equation. Linear for large positive v, exponentially decays for large negative v..

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

(from baseHHRate)

voltage

rate

(from baseHHRate)

per_time

scale

(from baseHHRate)

voltage

+
+ +
+ +++++ + + + + + + +

r

(from baseVoltageDepRate)

per_time

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepRate)

voltage

+
+ +
+
+
Derived Variables

x = (v - midpoint) / scale

+
+
Conditional Derived Variables

IF x != 0 THEN

+
+

r = rate * x / (1 - exp(0 - x))  (exposed as r)

+
+

IF x = 0 THEN

+
+

r = rate  (exposed as r)

+
+
+
+
+
+
+

baseVoltageDepVariable#

+

Base ComponentType for voltage dependent variable x, which depends on v. Can be used for inf/steady state of rate variable.

+
+ +
+ +++++ + + + + + + +

x

Dimensionless

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+
+
+
+

baseVoltageConcDepVariable#

+

extends baseVoltageDepVariable

+

Base ComponentType for voltage and calcium concentration dependent variable x, which depends on v and caConc..

+
+ +
+ +++++ + + + + + + +

x

(from baseVoltageDepVariable)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

caConc

concentration

v

(from baseVoltageDepVariable)

voltage

+
+
+
+
+

baseHHVariable#

+

extends baseVoltageDepVariable

+

Base ComponentType for voltage dependent dimensionless variable which follow one of the typical forms for variable equations in the standard HH formalism, using the parameters rate, midpoint, scale.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

voltage

rate

Dimensionless

scale

voltage

+
+ +
+ +++++ + + + + + + +

x

(from baseVoltageDepVariable)

Dimensionless

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepVariable)

voltage

+
+
+
+
+

HHExpVariable#

+

extends baseHHVariable

+

Exponential form for variable equation.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

(from baseHHVariable)

voltage

rate

(from baseHHVariable)

Dimensionless

scale

(from baseHHVariable)

voltage

+
+ +
+ +++++ + + + + + + +

x

(from baseVoltageDepVariable)

Dimensionless

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepVariable)

voltage

+
+ +
+
+
Derived Variables

x = rate * exp((v - midpoint)/scale) (exposed as x)

+
+
+
+
+
+
+

HHSigmoidVariable#

+

extends baseHHVariable

+

Sigmoidal form for variable equation.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

(from baseHHVariable)

voltage

rate

(from baseHHVariable)

Dimensionless

scale

(from baseHHVariable)

voltage

+
+ +
+ +++++ + + + + + + +

x

(from baseVoltageDepVariable)

Dimensionless

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepVariable)

voltage

+
+ +
+
+
Derived Variables

x = rate / (1 + exp(0 - (v - midpoint)/scale)) (exposed as x)

+
+
+
+
+
+
+

HHExpLinearVariable#

+

extends baseHHVariable

+

Exponential linear form for variable equation. Linear for large positive v, exponentially decays for large negative v..

+
+ +
+ +++++ + + + + + + + + + + + + + + +

midpoint

(from baseHHVariable)

voltage

rate

(from baseHHVariable)

Dimensionless

scale

(from baseHHVariable)

voltage

+
+ +
+ +++++ + + + + + + +

x

(from baseVoltageDepVariable)

Dimensionless

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepVariable)

voltage

+
+ +
+
+
Derived Variables

a = (v - midpoint) / scale

+
+

x = rate * a / (1 - exp(0 - a)) (exposed as x)

+
+
+
+
+
+
+

baseVoltageDepTime#

+

Base ComponentType for voltage dependent ComponentType producing value t with dimension time ( e.g. for time course of rate variable ). Note: time course would not normally be fit to exp/sigmoid etc.

+
+ +
+ +++++ + + + + + + +

t

time

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+
+
+
+

baseVoltageConcDepTime#

+

extends baseVoltageDepTime

+

Base type for voltage and calcium concentration dependent ComponentType producing value t with dimension time ( e.g. for time course of rate variable ).

+
+ +
+ +++++ + + + + + + +

t

(from baseVoltageDepTime)

time

+
+ +
+ +++++ + + + + + + + + + + +

caConc

concentration

v

(from baseVoltageDepTime)

voltage

+
+
+
+
+

fixedTimeCourse#

+

extends baseVoltageDepTime

+

Time course of a fixed magnitude tau which can be used for the time course in gateHHtauInf, gateHHratesTau or gateHHratesTauInf.

+
+ +
+ +++++ + + + + + + +

tau

time

+
+ +
+ +++++ + + + + + + +

t

(from baseVoltageDepTime)

time

+
+ +
+ +++++ + + + + + + +

v

(from baseVoltageDepTime)

voltage

+
+ +
+
+
Derived Variables

t = tau (exposed as t)

+
+
+
+
+
+
+

baseQ10Settings#

+

Base ComponentType for a scaling to apply to gating variable time course, usually temperature dependent.

+
+ +
+ +++++ + + + + + + +

q10

Dimensionless

+
+ +
+ +++++ + + + + + + +

temperature

temperature

+
+
+
+
+

q10Fixed#

+

extends baseQ10Settings

+

A fixed value, fixedQ10, for the scaling of the time course of the gating variable.

+
+ +
+ +++++ + + + + + + +

fixedQ10

Dimensionless

+
+ +
+ +++++ + + + + + + +

q10

(from baseQ10Settings)

Dimensionless

+
+ +
+ +++++ + + + + + + +

temperature

(from baseQ10Settings)

temperature

+
+ +
+
+
Derived Variables

q10 = fixedQ10 (exposed as q10)

+
+
+
+
+
+
+

q10ExpTemp#

+

extends baseQ10Settings

+

A value for the Q10 scaling which varies as a standard function of the difference between the current temperature, temperature, and the temperature at which the gating variable equations were determined, experimentalTemp.

+
+ +
+ +++++ + + + + + + + + + + +

experimentalTemp

temperature

q10Factor

Dimensionless

+
+ +
+ +++++ + + + + + + +

TENDEGREES = 10K

temperature

+
+ +
+ +++++ + + + + + + +

q10

(from baseQ10Settings)

Dimensionless

+
+ +
+ +++++ + + + + + + +

temperature

(from baseQ10Settings)

temperature

+
+ +
+
+
Derived Variables

q10 = q10Factor^((temperature - experimentalTemp)/TENDEGREES) (exposed as q10)

+
+
+
+
+
+
+

baseConductanceScaling#

+

Base ComponentType for a scaling to apply to a gate’s conductance, e.g. temperature dependent scaling.

+
+ +
+ +++++ + + + + + + +

factor

Dimensionless

+
+ +
+ +++++ + + + + + + +

temperature

temperature

+
+
+
+
+

q10ConductanceScaling#

+

extends baseConductanceScaling

+

A value for the conductance scaling which varies as a standard function of the difference between the current temperature, temperature, and the temperature at which the conductance was originally determined, experimentalTemp.

+
+ +
+ +++++ + + + + + + + + + + +

experimentalTemp

temperature

q10Factor

Dimensionless

+
+ +
+ +++++ + + + + + + +

TENDEGREES = 10K

temperature

+
+ +
+ +++++ + + + + + + +

factor

(from baseConductanceScaling)

Dimensionless

+
+ +
+ +++++ + + + + + + +

temperature

(from baseConductanceScaling)

temperature

+
+ +
+
+
Derived Variables

factor = q10Factor^((temperature - experimentalTemp)/TENDEGREES) (exposed as factor)

+
+
+
+ +
+
<xs:complexType name="Q10ConductanceScaling">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="q10Factor" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="experimentalTemp" type="Nml2Quantity_temperature" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Q10ConductanceScaling
+
+variable = Q10ConductanceScaling(
+    q10_factor: 'a Nml2Quantity_none (required)' = None,
+    experimental_temp: 'a Nml2Quantity_temperature (required)' = None,
+)
+
+
+
+
+
+
+

baseConductanceScalingCaDependent#

+

extends baseConductanceScaling

+

Base ComponentType for a scaling to apply to a gate’s conductance which depends on Ca concentration. Usually a generic expression of caConc ( so no standard, non-base form here ).

+
+ +
+ +++++ + + + + + + +

factor

(from baseConductanceScaling)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

caConc

concentration

temperature

(from baseConductanceScaling)

temperature

+
+
+
+
+

baseGate#

+

Base ComponentType for a voltage and/or concentration dependent gate.

+
+ +
+ +++++ + + + + + + +

instances

Dimensionless

+
+ +
+ +++++ + + + + + + +

notes

notes

+
+ +
+ +++++ + + + + + + + + + + +

fcond

Dimensionless

q

Dimensionless

+
+
+
+
+

gate#

+

extends baseGate

+

Conveniently named baseGate.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

fcond

(from baseGate)

Dimensionless

q

(from baseGate)

Dimensionless

+
+
+
+
+

gateHHrates#

+

extends gate

+

Gate which follows the general Hodgkin Huxley formalism.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

forwardRate

baseVoltageDepRate

reverseRate

baseVoltageDepRate

+
+ +
+ +++++ + + + + + + +

q10Settings

baseQ10Settings

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

alpha

per_time

beta

per_time

fcond

(from baseGate)

Dimensionless

inf

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

tau

time

+
+ +
+
+
State Variables

q: Dimensionless  (exposed as q)

+
+
On Start

q = inf

+
+
Derived Variables

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+

alpha = forwardRate->r (exposed as alpha)

+
+

beta = reverseRate->r (exposed as beta)

+
+

fcond = q^instances (exposed as fcond)

+
+

inf = alpha/(alpha+beta) (exposed as inf)

+
+

tau = 1/((alpha+beta) * rateScale) (exposed as tau)

+
+
Time Derivatives

d q /dt = (inf - q) / tau

+
+
+
+ +
+
<xs:complexType name="GateHHRates">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="forwardRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="reverseRate" type="HHRate" minOccurs="1"/>
+      </xs:all>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+
<gateHHrates id="m" instances="3">
+            <forwardRate type="HHExpLinearRate" rate="1per_ms" midpoint="-40mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV"/>
+        </gateHHrates>
+
+
+
<gateHHrates id="h" instances="1">
+            <forwardRate type="HHExpRate" rate="0.07per_ms" midpoint="-65mV" scale="-20mV"/>
+            <reverseRate type="HHSigmoidRate" rate="1per_ms" midpoint="-35mV" scale="10mV"/>
+        </gateHHrates>
+
+
+
<gateHHrates id="m" instances="3">
+            <forwardRate type="HHExpLinearRate" rate="1per_ms" midpoint="-40mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV"/>
+        </gateHHrates>
+
+
+
+
+
+
+

gateHHtauInf#

+

extends gate

+

Gate which follows the general Hodgkin Huxley formalism.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

timeCourse

baseVoltageDepTime

steadyState

baseVoltageDepVariable

+
+ +
+ +++++ + + + + + + +

q10Settings

baseQ10Settings

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

fcond

(from baseGate)

Dimensionless

inf

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

tau

time

+
+ +
+
+
State Variables

q: Dimensionless  (exposed as q)

+
+
On Start

q = inf

+
+
Derived Variables

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+

fcond = q^instances (exposed as fcond)

+
+

inf = steadyState->x (exposed as inf)

+
+

tauUnscaled = timeCourse->t

+
+

tau = tauUnscaled / rateScale (exposed as tau)

+
+
Time Derivatives

d q /dt = (inf - q) / tau

+
+
+
+ +
+
<xs:complexType name="GateHHTauInf">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="timeCourse" type="HHTime" minOccurs="1"/>
+        <xs:element name="steadyState" type="HHVariable" minOccurs="1"/>
+      </xs:all>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

gateHHInstantaneous#

+

extends gate

+

Gate which follows the general Hodgkin Huxley formalism but is instantaneous, so tau = 0 and gate follows exactly inf value.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + +

SEC = 1 s

time

+
+ +
+ +++++ + + + + + + +

steadyState

baseVoltageDepVariable

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

fcond

(from baseGate)

Dimensionless

inf

Dimensionless

q

(from baseGate)

Dimensionless

tau

time

+
+ +
+
+
Derived Variables

inf = steadyState->x (exposed as inf)

+
+

tau = 0 * SEC (exposed as tau)

+
+

q = inf (exposed as q)

+
+

fcond = q^instances (exposed as fcond)

+
+
+
+ +
+
<xs:complexType name="GateHHInstantaneous">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="steadyState" type="HHVariable" minOccurs="1"/>
+      </xs:all>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import GateHHInstantaneous
+
+variable = GateHHInstantaneous(
+    id: 'a NmlId (required)' = None,
+    instances: 'a PositiveInteger (required)' = None,
+    notes: 'a string (optional)' = None,
+    steady_state: 'a HHVariable (required)' = None,
+)
+
+
+
+
+
+
+

gateHHratesTau#

+

extends gate

+

Gate which follows the general Hodgkin Huxley formalism.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

forwardRate

baseVoltageDepRate

reverseRate

baseVoltageDepRate

timeCourse

baseVoltageDepTime

+
+ +
+ +++++ + + + + + + +

q10Settings

baseQ10Settings

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

alpha

per_time

beta

per_time

fcond

(from baseGate)

Dimensionless

inf

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

tau

time

+
+ +
+
+
State Variables

q: Dimensionless  (exposed as q)

+
+
On Start

q = inf

+
+
Derived Variables

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+

alpha = forwardRate->r (exposed as alpha)

+
+

beta = reverseRate->r (exposed as beta)

+
+

fcond = q^instances (exposed as fcond)

+
+

inf = alpha/(alpha+beta) (exposed as inf)

+
+

tauUnscaled = timeCourse->t

+
+

tau = tauUnscaled / rateScale (exposed as tau)

+
+
Time Derivatives

d q /dt = (inf - q) / tau

+
+
+
+ +
+
<xs:complexType name="GateHHRatesTau">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="forwardRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="reverseRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="timeCourse" type="HHTime" minOccurs="1"/>
+      </xs:all>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

gateHHratesInf#

+

extends gate

+

Gate which follows the general Hodgkin Huxley formalism.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

forwardRate

baseVoltageDepRate

reverseRate

baseVoltageDepRate

steadyState

baseVoltageDepVariable

+
+ +
+ +++++ + + + + + + +

q10Settings

baseQ10Settings

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

alpha

per_time

beta

per_time

fcond

(from baseGate)

Dimensionless

inf

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

tau

time

+
+ +
+
+
State Variables

q: Dimensionless  (exposed as q)

+
+
On Start

q = inf

+
+
Derived Variables

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+

alpha = forwardRate->r (exposed as alpha)

+
+

beta = reverseRate->r (exposed as beta)

+
+

fcond = q^instances (exposed as fcond)

+
+

inf = steadyState->x (exposed as inf)

+
+

tau = 1/((alpha+beta) * rateScale) (exposed as tau)

+
+
Time Derivatives

d q /dt = (inf - q) / tau

+
+
+
+ +
+
<xs:complexType name="GateHHRatesInf">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="forwardRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="reverseRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="steadyState" type="HHVariable" minOccurs="1"/>
+      </xs:all>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

gateHHratesTauInf#

+

extends gate

+

Gate which follows the general Hodgkin Huxley formalism.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

forwardRate

baseVoltageDepRate

reverseRate

baseVoltageDepRate

timeCourse

baseVoltageDepTime

steadyState

baseVoltageDepVariable

+
+ +
+ +++++ + + + + + + +

q10Settings

baseQ10Settings

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

alpha

per_time

beta

per_time

fcond

(from baseGate)

Dimensionless

inf

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

tau

time

+
+ +
+
+
State Variables

q: Dimensionless  (exposed as q)

+
+
On Start

q = inf

+
+
Derived Variables

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+

alpha = forwardRate->r (exposed as alpha)

+
+

beta = reverseRate->r (exposed as beta)

+
+

inf = steadyState->x (exposed as inf)

+
+

tauUnscaled = timeCourse->t

+
+

tau = tauUnscaled / rateScale (exposed as tau)

+
+

fcond = q^instances (exposed as fcond)

+
+
Time Derivatives

d q /dt = (inf - q) / tau

+
+
+
+ +
+
<xs:complexType name="GateHHRatesTauInf">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="forwardRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="reverseRate" type="HHRate" minOccurs="1"/>
+        <xs:element name="timeCourse" type="HHTime" minOccurs="1"/>
+        <xs:element name="steadyState" type="HHVariable" minOccurs="1"/>
+      </xs:all>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

gateFractional#

+

extends gate

+

Gate composed of subgates contributing with fractional conductance.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

q10Settings

baseQ10Settings

subGate

subGate

+
+ +
+ +++++ + + + + + + + + + + + + + + +

fcond

(from baseGate)

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

+
+ +
+
+
Derived Variables

q = subGate[*]->qfrac(reduce method: add) (exposed as q)

+
+

fcond = q^instances (exposed as fcond)

+
+

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+
+
+ +
+
<xs:complexType name="GateFractional">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="subGate" type="GateFractionalSubgate" minOccurs="1" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import GateFractional
+
+variable = GateFractional(
+    id: 'a NmlId (required)' = None,
+    instances: 'a PositiveInteger (required)' = None,
+    notes: 'a string (optional)' = None,
+    q10_settings: 'a Q10Settings (optional)' = None,
+    sub_gates: 'list of GateFractionalSubgate(s) (required)' = None,
+)
+
+
+
+
+
+
+

subGate#

+

Gate composed of subgates contributing with fractional conductance.

+
+ +
+ +++++ + + + + + + +

fractionalConductance

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

notes

notes

timeCourse

baseVoltageDepTime

steadyState

baseVoltageDepVariable

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

inf

Dimensionless

q

Dimensionless

qfrac

Dimensionless

tau

time

+
+ +
+ +++++ + + + + + + +

rateScale

Dimensionless

+
+ +
+
+
State Variables

q: Dimensionless  (exposed as q)

+
+
On Start

q = inf

+
+
Derived Variables

inf = steadyState->x (exposed as inf)

+
+

tauUnscaled = timeCourse->t

+
+

tau = tauUnscaled / rateScale (exposed as tau)

+
+

qfrac = q * fractionalConductance (exposed as qfrac)

+
+
Time Derivatives

d q /dt = (inf - q) / tau

+
+
+
+
+
+
+

baseIonChannel#

+

Base for all ion channel ComponentTypes.

+
+ +
+ +++++ + + + + + + +

conductance

conductance

+
+ +
+ ++++ + + + + + +

neuroLexId

+
+ +
+ +++++ + + + + + + + + + + +

notes

notes

annotation

annotation

+
+ +
+ +++++ + + + + + + + + + + +

fopen

Dimensionless

g

conductance

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+
+
+
+

ionChannelPassive#

+

extends ionChannel

+

Simple passive ion channel where the constant conductance through the channel is equal to conductance.

+
+ +
+ +++++ + + + + + + +

conductance

(from baseIonChannel)

conductance

+
+ +
+ ++++ + + + + + +

species

+
+ +
+ +++++ + + + + + + + + + + +

fopen

(from baseIonChannel)

Dimensionless

g

(from baseIonChannel)

conductance

+
+ +
+ +++++ + + + + + + +

v

(from baseIonChannel)

voltage

+
+ +
+
+
Derived Variables

fopen = 1 (exposed as fopen)

+
+

g = conductance (exposed as g)

+
+
+
+
+
+
+

ionChannelHH#

+

extends baseIonChannel

+

Note ionChannel and ionChannelHH are currently functionally identical. This is needed since many existing examples use ionChannel, some use ionChannelHH. NeuroML v2beta4 should remove one of these, probably ionChannelHH.

+
+ +
+ +++++ + + + + + + +

conductance

(from baseIonChannel)

conductance

+
+ +
+ ++++ + + + + + +

species

+
+ +
+ +++++ + + + + + + + + + + +

conductanceScaling

baseConductanceScaling

gates

gate

+
+ +
+ +++++ + + + + + + + + + + +

fopen

(from baseIonChannel)

Dimensionless

g

(from baseIonChannel)

conductance

+
+ +
+ +++++ + + + + + + +

v

(from baseIonChannel)

voltage

+
+ +
+
+
Derived Variables

conductanceScale = conductanceScaling[*]->factor(reduce method: multiply)

+
+

fopen0 = gates[*]->fcond(reduce method: multiply)

+
+

fopen = conductanceScale * fopen0 (exposed as fopen)

+
+

g = conductance * fopen (exposed as g)

+
+
+
+ +
+
<xs:complexType name="IonChannelHH">
+  <xs:complexContent>
+    <xs:extension base="IonChannel"/>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IonChannelHH
+
+variable = IonChannelHH(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    q10_conductance_scalings: 'list of Q10ConductanceScaling(s) (optional)' = None,
+    species: 'a NmlId (optional)' = None,
+    type: 'a channelTypes (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (optional)' = None,
+    gates: 'list of GateHHUndetermined(s) (optional)' = None,
+    gate_hh_rates: 'list of GateHHRates(s) (optional)' = None,
+    gate_h_hrates_taus: 'list of GateHHRatesTau(s) (optional)' = None,
+    gate_hh_tau_infs: 'list of GateHHTauInf(s) (optional)' = None,
+    gate_h_hrates_infs: 'list of GateHHRatesInf(s) (optional)' = None,
+    gate_h_hrates_tau_infs: 'list of GateHHRatesTauInf(s) (optional)' = None,
+    gate_hh_instantaneouses: 'list of GateHHInstantaneous(s) (optional)' = None,
+    gate_fractionals: 'list of GateFractional(s) (optional)' = None,
+)
+
+
+
+ +
+
<ionChannelHH id="pas" conductance="10pS"/>
+
+
+
<ionChannelHH id="HH_Na" conductance="10pS" species="na">  
+        
+    </ionChannelHH>
+
+
+
<ionChannelHH id="NaConductance" conductance="10pS" species="na">
+        <gateHHrates id="m" instances="3">
+            <forwardRate type="HHExpLinearRate" rate="1per_ms" midpoint="-40mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV"/>
+        </gateHHrates>
+        <gateHHrates id="h" instances="1">
+            <forwardRate type="HHExpRate" rate="0.07per_ms" midpoint="-65mV" scale="-20mV"/>
+            <reverseRate type="HHSigmoidRate" rate="1per_ms" midpoint="-35mV" scale="10mV"/>
+        </gateHHrates>
+    </ionChannelHH>
+
+
+
+
+
+
+

ionChannel#

+

extends ionChannelHH

+

Note ionChannel and ionChannelHH are currently functionally identical. This is needed since many existing examples use ionChannel, some use ionChannelHH. NeuroML v2beta4 should remove one of these, probably ionChannelHH.

+
+ +
+ +++++ + + + + + + +

conductance

(from baseIonChannel)

conductance

+
+ +
+ +++++ + + + + + + + + + + +

fopen

(from baseIonChannel)

Dimensionless

g

(from baseIonChannel)

conductance

+
+ +
+ +++++ + + + + + + +

v

(from baseIonChannel)

voltage

+
+ +
+
+
Derived Variables

conductanceScale = conductanceScaling[*]->factor(reduce method: multiply)

+
+

fopen0 = gates[*]->fcond(reduce method: multiply)

+
+

fopen = conductanceScale * fopen0 (exposed as fopen)

+
+

g = conductance * fopen (exposed as g)

+
+
+
+ +
+
<xs:complexType name="IonChannel">
+  <xs:complexContent>
+    <xs:extension base="IonChannelScalable">
+      <xs:choice>
+        <xs:element name="gate" type="GateHHUndetermined" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateHHrates" type="GateHHRates" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateHHratesTau" type="GateHHRatesTau" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateHHtauInf" type="GateHHTauInf" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateHHratesInf" type="GateHHRatesInf" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateHHratesTauInf" type="GateHHRatesTauInf" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateHHInstantaneous" type="GateHHInstantaneous" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="gateFractional" type="GateFractional" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:choice>
+      <xs:attribute name="species" type="NmlId" use="optional"/>
+      <xs:attribute name="type" type="channelTypes" use="optional"/>
+      <xs:attribute name="conductance" type="Nml2Quantity_conductance" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IonChannel
+
+variable = IonChannel(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    q10_conductance_scalings: 'list of Q10ConductanceScaling(s) (optional)' = None,
+    species: 'a NmlId (optional)' = None,
+    type: 'a channelTypes (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (optional)' = None,
+    gates: 'list of GateHHUndetermined(s) (optional)' = None,
+    gate_hh_rates: 'list of GateHHRates(s) (optional)' = None,
+    gate_h_hrates_taus: 'list of GateHHRatesTau(s) (optional)' = None,
+    gate_hh_tau_infs: 'list of GateHHTauInf(s) (optional)' = None,
+    gate_h_hrates_infs: 'list of GateHHRatesInf(s) (optional)' = None,
+    gate_h_hrates_tau_infs: 'list of GateHHRatesTauInf(s) (optional)' = None,
+    gate_hh_instantaneouses: 'list of GateHHInstantaneous(s) (optional)' = None,
+    gate_fractionals: 'list of GateFractional(s) (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

ionChannelVShift#

+

extends ionChannel

+

Same as ionChannel, but with a vShift parameter to change voltage activation of gates. The exact usage of vShift in expressions for rates is determined by the individual gates.

+
+ +
+ +++++ + + + + + + + + + + +

conductance

(from baseIonChannel)

conductance

vShift

voltage

+
+ +
+ ++++ + + + + + +

species

+
+ +
+ +++++ + + + + + + + + + + +

fopen

(from baseIonChannel)

Dimensionless

g

(from baseIonChannel)

conductance

+
+ +
+ +++++ + + + + + + +

v

(from baseIonChannel)

voltage

+
+ +
+
<xs:complexType name="IonChannelVShift">
+  <xs:complexContent>
+    <xs:extension base="IonChannel">
+      <xs:attribute name="vShift" type="Nml2Quantity_voltage" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IonChannelVShift
+
+variable = IonChannelVShift(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    q10_conductance_scalings: 'list of Q10ConductanceScaling(s) (optional)' = None,
+    species: 'a NmlId (optional)' = None,
+    type: 'a channelTypes (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (optional)' = None,
+    gates: 'list of GateHHUndetermined(s) (optional)' = None,
+    gate_hh_rates: 'list of GateHHRates(s) (optional)' = None,
+    gate_h_hrates_taus: 'list of GateHHRatesTau(s) (optional)' = None,
+    gate_hh_tau_infs: 'list of GateHHTauInf(s) (optional)' = None,
+    gate_h_hrates_infs: 'list of GateHHRatesInf(s) (optional)' = None,
+    gate_h_hrates_tau_infs: 'list of GateHHRatesTauInf(s) (optional)' = None,
+    gate_hh_instantaneouses: 'list of GateHHInstantaneous(s) (optional)' = None,
+    gate_fractionals: 'list of GateFractional(s) (optional)' = None,
+    v_shift: 'a Nml2Quantity_voltage (required)' = None,
+)
+
+
+
+
+
+
+

KSState#

+

One of the states in which a gateKS can be. The rates of transitions between these states are given by KSTransitions.

+
+ +
+ +++++ + + + + + + +

relativeConductance

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

occupancy

Dimensionless

q

Dimensionless

+
+ +
+
+
State Variables

occupancy: Dimensionless  (exposed as occupancy)

+
+
Derived Variables

q = relativeConductance * occupancy (exposed as q)

+
+
+
+
+
+
+

closedState#

+

extends KSState

+

A KSState with relativeConductance of 0.

+
+ +
+ +++++ + + + + + + +

relativeConductance

(from KSState)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

occupancy

(from KSState)

Dimensionless

q

(from KSState)

Dimensionless

+
+ +
+
<xs:complexType name="ClosedState">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ClosedState
+
+variable = ClosedState(
+    id: 'a NmlId (required)' = None,
+)
+
+
+
+
+
+
+

openState#

+

extends KSState

+

A KSState with relativeConductance of 1.

+
+ +
+ +++++ + + + + + + +

relativeConductance

(from KSState)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

occupancy

(from KSState)

Dimensionless

q

(from KSState)

Dimensionless

+
+ +
+
<xs:complexType name="OpenState">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import OpenState
+
+variable = OpenState(
+    id: 'a NmlId (required)' = None,
+)
+
+
+
+
+
+
+

ionChannelKS#

+

extends baseIonChannel

+

A kinetic scheme based ion channel with multiple gateKSs, each of which consists of multiple KSStates and KSTransitions giving the rates of transition between them.

+
+ +
+ +++++ + + + + + + +

conductance

(from baseIonChannel)

conductance

+
+ +
+ ++++ + + + + + +

species

+
+ +
+ +++++ + + + + + + + + + + +

conductanceScaling

baseConductanceScaling

gates

gateKS

+
+ +
+ +++++ + + + + + + + + + + +

fopen

(from baseIonChannel)

Dimensionless

g

(from baseIonChannel)

conductance

+
+ +
+ +++++ + + + + + + +

v

(from baseIonChannel)

voltage

+
+ +
+
+
Derived Variables

fopen = gates[*]->fcond(reduce method: multiply) (exposed as fopen)

+
+

g = fopen * conductance (exposed as g)

+
+
+
+ +
+
<xs:complexType name="IonChannelKS">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="gateKS" type="GateKS" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="species" type="NmlId" use="optional"/>
+      <xs:attribute name="conductance" type="Nml2Quantity_conductance" use="optional"/>
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IonChannelKS
+
+variable = IonChannelKS(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    species: 'a NmlId (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gate_kses: 'list of GateKS(s) (optional)' = None,
+)
+
+
+
+
+
+
+

KSTransition#

+

Specified the forward and reverse rates of transition between two KSStates in a gateKS.

+
+ +
+ +++++ + + + + + + + + + + +

rf

per_time

rr

per_time

+
+
+
+
+

forwardTransition#

+

extends KSTransition

+

A forward only KSTransition for a gateKS which specifies a rate ( type baseHHRate ) which follows one of the standard Hodgkin Huxley forms ( e.g. HHExpRate, HHSigmoidRate, HHExpLinearRate.

+
+ +
+ +++++ + + + + + + +

SEC = 1s

time

+
+ +
+ +++++ + + + + + + +

rate

baseHHRate

+
+ +
+ +++++ + + + + + + + + + + +

rf

(from KSTransition)

per_time

rr

(from KSTransition)

per_time

+
+ +
+
+
Derived Variables

rf0 = rate->r

+
+

rf = rf0 (exposed as rf)

+
+

rr = 0/SEC (exposed as rr)

+
+
+
+ +
+
<xs:complexType name="ForwardTransition">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="from" type="NmlId" use="required"/>
+      <xs:attribute name="to" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ForwardTransition
+
+variable = ForwardTransition(
+    id: 'a NmlId (required)' = None,
+    from_: 'a NmlId (required)' = None,
+    to: 'a NmlId (required)' = None,
+    anytypeobjs_=None,
+)
+
+
+
+
+
+
+

reverseTransition#

+

extends KSTransition

+

A reverse only KSTransition for a gateKS which specifies a rate ( type baseHHRate ) which follows one of the standard Hodgkin Huxley forms ( e.g. HHExpRate, HHSigmoidRate, HHExpLinearRate.

+
+ +
+ +++++ + + + + + + +

SEC = 1s

time

+
+ +
+ +++++ + + + + + + +

rate

baseHHRate

+
+ +
+ +++++ + + + + + + + + + + +

rf

(from KSTransition)

per_time

rr

(from KSTransition)

per_time

+
+ +
+
+
Derived Variables

rr0 = rate->r

+
+

rr = rr0 (exposed as rr)

+
+

rf = 0/SEC (exposed as rf)

+
+
+
+ +
+
<xs:complexType name="ReverseTransition">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="from" type="NmlId" use="required"/>
+      <xs:attribute name="to" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ReverseTransition
+
+variable = ReverseTransition(
+    id: 'a NmlId (required)' = None,
+    from_: 'a NmlId (required)' = None,
+    to: 'a NmlId (required)' = None,
+    anytypeobjs_=None,
+)
+
+
+
+
+
+
+

vHalfTransition#

+

extends KSTransition

+

Transition which specifies both the forward and reverse rates of transition.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

gamma

Dimensionless

tau

time

tauMin

time

vHalf

voltage

z

Dimensionless

+
+ +
+ +++++ + + + + + + +

kte = 25.3mV

voltage

+
+ +
+ +++++ + + + + + + + + + + +

rf

(from KSTransition)

per_time

rr

(from KSTransition)

per_time

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+ +
+
+
Derived Variables

rf0 = exp(z * gamma * (v - vHalf) / kte) / tau

+
+

rr0 = exp(-z * (1 - gamma) * (v - vHalf) / kte) / tau

+
+

rf = 1 / (1/rf0 + tauMin) (exposed as rf)

+
+

rr = 1 / (1/rr0 + tauMin) (exposed as rr)

+
+
+
+
+
+
+

tauInfTransition#

+

extends KSTransition

+

KS Transition specified in terms of time constant schema:tau and steady state schema:inf.

+
+ +
+ +++++ + + + + + + + + + + +

timeCourse

baseVoltageDepTime

steadyState

baseVoltageDepVariable

+
+ +
+ +++++ + + + + + + + + + + +

rf

(from KSTransition)

per_time

rr

(from KSTransition)

per_time

+
+ +
+
+
Derived Variables

tau = timeCourse->t

+
+

inf = steadyState->x

+
+

rf = inf/tau (exposed as rf)

+
+

rr = (1-inf)/tau (exposed as rr)

+
+
+
+ +
+
<xs:complexType name="TauInfTransition">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:all>
+        <xs:element name="steadyState" type="HHVariable"/>
+        <xs:element name="timeCourse" type="HHTime"/>
+      </xs:all>
+      <xs:attribute name="from" type="NmlId" use="required"/>
+      <xs:attribute name="to" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import TauInfTransition
+
+variable = TauInfTransition(
+    id: 'a NmlId (required)' = None,
+    from_: 'a NmlId (required)' = None,
+    to: 'a NmlId (required)' = None,
+    steady_state: 'a HHVariable (required)' = None,
+    time_course: 'a HHTime (required)' = None,
+)
+
+
+
+
+
+
+

gateKS#

+

extends baseGate

+

A gate which consists of multiple KSStates and KSTransitions giving the rates of transition between them.

+
+ +
+ +++++ + + + + + + +

instances

(from baseGate)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

states

KSState

transitions

KSTransition

q10Settings

baseQ10Settings

+
+ +
+ +++++ + + + + + + + + + + + + + + +

fcond

(from baseGate)

Dimensionless

q

(from baseGate)

Dimensionless

rateScale

Dimensionless

+
+ +
+
+
Derived Variables

rateScale = q10Settings[*]->q10(reduce method: multiply) (exposed as rateScale)

+
+

q = states[*]->q(reduce method: add) (exposed as q)

+
+

fcond = q^instances (exposed as fcond)

+
+
+
+ +
+
<xs:complexType name="GateKS">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="notes" type="Notes" minOccurs="0"/>
+        <xs:element name="q10Settings" type="Q10Settings" minOccurs="0"/>
+        <xs:element name="closedState" type="ClosedState" minOccurs="1" maxOccurs="unbounded"/>
+        <xs:element name="openState" type="OpenState" minOccurs="1" maxOccurs="unbounded"/>
+        <xs:choice minOccurs="1" maxOccurs="unbounded">
+          <xs:group ref="ForwardReverseTransition"/>
+          <xs:element name="tauInfTransition" type="TauInfTransition"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="instances" type="PositiveInteger" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import GateKS
+
+variable = GateKS(
+    id: 'a NmlId (required)' = None,
+    instances: 'a PositiveInteger (required)' = None,
+    notes: 'a string (optional)' = None,
+    q10_settings: 'a Q10Settings (optional)' = None,
+    closed_states: 'list of ClosedState(s) (required)' = None,
+    open_states: 'list of OpenState(s) (required)' = None,
+    forward_transition: 'list of ForwardTransition(s) (required)' = None,
+    reverse_transition: 'list of ReverseTransition(s) (required)' = None,
+    tau_inf_transition: 'list of TauInfTransition(s) (required)' = None,
+)
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Index.html b/Userdocs/Schemas/Index.html new file mode 100644 index 00000000..0faec8b3 --- /dev/null +++ b/Userdocs/Schemas/Index.html @@ -0,0 +1,1185 @@ + + + + + + + + + + + Index — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Index

+ +
+
+ +
+
+
+ + + + +
+ +
+

Index#

+ + +
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Inputs.html b/Userdocs/Schemas/Inputs.html new file mode 100644 index 00000000..b8a28bc0 --- /dev/null +++ b/Userdocs/Schemas/Inputs.html @@ -0,0 +1,4172 @@ + + + + + + + + + + + Inputs — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Inputs#

+

A number of ComponentTypes for providing spiking ( e.g. spikeGeneratorPoisson, spikeArray ) and current inputs ( e.g. pulseGenerator, voltageClamp, timedSynapticInput, poissonFiringSynapse ) to other ComponentTypes

+
+

Original ComponentType definitions: Inputs.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

basePointCurrent#

+

extends baseStandalone

+

Base type for all ComponentTypes which produce a current i ( with dimension current ).

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType

current

+
+
+
+
+

baseVoltageDepPointCurrent#

+

extends basePointCurrent

+

Base type for all ComponentTypes which produce a current i ( with dimension current ) and require a voltage v exposed on the parent Component, which would often be the membrane potential of a Component extending baseCellMembPot.

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed

voltage

+
+
+
+
+

baseVoltageDepPointCurrentSpiking#

+

extends baseVoltageDepPointCurrent

+

Base type for all ComponentTypes which produce a current i, require a membrane potential v exposed on the parent and emit spikes ( on a port spike ). The exposed variable tsince can be used for plotting the time since the Component has spiked last.

+
+ +
+ +++++ + + + + + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

tsince

Time since the last spike was emitted

time

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted

Direction: out

+
+
+
+
+

basePointCurrentDL#

+

Base type for all ComponentTypes which produce a dimensionless current I. There are many dimensionless equivalents of all the core current producing ComponentTypes such as pulseGenerator / pulseGeneratorDL, sineGenerator / sineGeneratorDL and rampGenerator / rampGeneratorDL.

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType

Dimensionless

+
+
+
+
+

baseVoltageDepPointCurrentDL#

+

extends basePointCurrentDL

+

Base type for all ComponentTypes which produce a dimensionless current I and require a dimensionless membrane potential V exposed on the parent Component.

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType (from basePointCurrentDL)

Dimensionless

+
+ +
+ +++++ + + + + + + +

V

The current may vary with the dimensionless voltage exposed by the ComponentType on which this is placed

Dimensionless

+
+
+
+
+

baseSpikeSource#

+

Base for any ComponentType whose main purpose is to emit spikes ( on a port spike ). The exposed variable tsince can be used for plotting the time since the Component has spiked last.

+
+ +
+ +++++ + + + + + + +

tsince

Time since the last spike was emitted

time

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted

Direction: out

+
+
+
+
+

spikeGenerator#

+

extends baseSpikeSource

+

Simple generator of spikes at a regular interval set by period.

+
+ +
+ +++++ + + + + + + +

period

Time between spikes. The first spike will be emitted after this time.

time

+
+ +
+ +++++ + + + + + + +

SMALL_TIME = 1e-9ms

time

+
+ +
+ +++++ + + + + + + + + + + +

tnext

When the next spike should ideally be emitted (dt permitting)

time

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnext: time  (exposed as tnext)

+
+
On Start

tsince = 0

+
+

tnext = period

+
+
On Conditions

IF tnext - t < SMALL_TIME THEN

+
+

   tsince = 0

+
+

   tnext = tnext+period

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnext /dt = 0

+
+
+
+ +
+
<xs:complexType name="SpikeGenerator">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="period" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeGenerator
+
+variable = SpikeGenerator(
+    id: 'a NonNegativeInteger (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    period: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<spikeGenerator id="spikeGenRegular" period="20 ms"/>
+
+
+
+
+
+
+

spikeGeneratorRandom#

+

extends baseSpikeSource

+

Generator of spikes with a random interspike interval of at least minISI and at most maxISI.

+
+ +
+ +++++ + + + + + + + + + + +

maxISI

Maximum interspike interval

time

minISI

Minimum interspike interval

time

+
+ +
+ +++++ + + + + + + +

MSEC = 1ms

time

+
+ +
+ +++++ + + + + + + + + + + + + + + +

isi

The interval until the next spike

time

tnext

When the next spike should ideally be emitted (dt permitting)

time

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnext: time  (exposed as tnext)

+
+

isi: time  (exposed as isi)

+
+
On Start

tsince = 0

+
+

isi = minISI + MSEC * random((maxISI - minISI) / MSEC)

+
+

tnext = isi

+
+
On Conditions

IF t > tnext THEN

+
+

   isi = minISI + MSEC * random((maxISI - minISI) / MSEC)

+
+

   tsince = 0

+
+

   tnext = tnext+isi

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnext /dt = 0

+
+
+
+ +
+
<xs:complexType name="SpikeGeneratorRandom">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="maxISI" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="minISI" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeGeneratorRandom
+
+variable = SpikeGeneratorRandom(
+    id: 'a NonNegativeInteger (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    max_isi: 'a Nml2Quantity_time (required)' = None,
+    min_isi: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<spikeGeneratorRandom id="spikeGenRandom" minISI="10 ms" maxISI="30 ms"/>
+
+
+
+
+
+
+

spikeGeneratorPoisson#

+

extends baseSpikeSource

+

Generator of spikes whose ISI is distributed according to an exponential PDF with scale: 1 / averageRate.

+
+ +
+ +++++ + + + + + + +

averageRate

The average rate at which spikes are emitted

per_time

+
+ +
+ +++++ + + + + + + +

SMALL_TIME = 1e-9ms

time

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

isi

The interval until the next spike

time

tnextIdeal

This is the ideal/perfect next spike time, based on a newly generated isi, but dt precision will mean that it’s usually slightly later than this

time

tnextUsed

This is the next spike time for practical purposes, ensuring that it’s later than the current time

time

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnextIdeal: time  (exposed as tnextIdeal)

+
+

tnextUsed: time  (exposed as tnextUsed)

+
+

isi: time  (exposed as isi)

+
+
On Start

tsince = 0

+
+

isi = -1 * log(random(1)) / averageRate

+
+

tnextIdeal = isi

+
+

tnextUsed = isi

+
+
On Conditions

IF t > tnextUsed THEN

+
+

   tsince = 0

+
+

   isi = -1 * log(random(1)) / averageRate

+
+

   tnextIdeal = (tnextIdeal+isi)

+
+

   tnextUsed = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t )

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnextUsed /dt = 0

+
+

d tnextIdeal /dt = 0

+
+
+
+ +
+
<xs:complexType name="SpikeGeneratorPoisson">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="averageRate" type="Nml2Quantity_pertime" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeGeneratorPoisson
+
+variable = SpikeGeneratorPoisson(
+    id: 'a NonNegativeInteger (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    average_rate: 'a Nml2Quantity_pertime (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<spikeGeneratorPoisson id="spikeGenPoisson" averageRate="50 Hz"/>
+
+
+
+
+
+
+

spikeGeneratorRefPoisson#

+

extends spikeGeneratorPoisson

+

Generator of spikes whose ISI distribution is the maximum entropy distribution over [ minimumISI, +infinity ) with mean: 1 / averageRate.

+
+ +
+ +++++ + + + + + + + + + + +

averageRate

The average rate at which spikes are emitted (from spikeGeneratorPoisson)

per_time

minimumISI

The minimum interspike interval

time

+
+ +
+ +++++ + + + + + + +

averageIsi

The average interspike interval

time

+

   averageIsi = 1 / averageRate

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

isi

The interval until the next spike (from spikeGeneratorPoisson)

time

tnextIdeal

This is the ideal/perfect next spike time, based on a newly generated isi, but dt precision will mean that it’s usually slightly later than this (from spikeGeneratorPoisson)

time

tnextUsed

This is the next spike time for practical purposes, ensuring that it’s later than the current time (from spikeGeneratorPoisson)

time

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnextIdeal: time  (exposed as tnextIdeal)

+
+

tnextUsed: time  (exposed as tnextUsed)

+
+

isi: time  (exposed as isi)

+
+
On Start

tsince = 0

+
+

isi = minimumISI - (averageIsi-minimumISI) * log(random(1))

+
+

tnextIdeal = isi

+
+

tnextUsed = isi

+
+
On Conditions

IF t > tnextUsed THEN

+
+

   tsince = 0

+
+

   isi = minimumISI - (averageIsi-minimumISI) * log(random(1))

+
+

   tnextIdeal = (tnextIdeal+isi)

+
+

   tnextUsed = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t )

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnextUsed /dt = 0

+
+

d tnextIdeal /dt = 0

+
+
+
+ +
+
<xs:complexType name="SpikeGeneratorRefPoisson">
+  <xs:complexContent>
+    <xs:extension base="SpikeGeneratorPoisson">
+      <xs:attribute name="minimumISI" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeGeneratorRefPoisson
+
+variable = SpikeGeneratorRefPoisson(
+    id: 'a NonNegativeInteger (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    average_rate: 'a Nml2Quantity_pertime (required)' = None,
+    minimum_isi: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<spikeGeneratorRefPoisson id="spikeGenRefPoisson" averageRate="50 Hz" minimumISI="10 ms"/>
+
+
+
+
+
+
+

poissonFiringSynapse#

+

extends baseVoltageDepPointCurrentSpiking

+

Poisson spike generator firing at averageRate, which is connected to single synapse that is triggered every time a spike is generated, producing an input current. See also transientPoissonFiringSynapse.

+
+ +
+ +++++ + + + + + + +

averageRate

The average rate at which spikes are emitted

per_time

+
+ +
+ +++++ + + + + + + +

SMALL_TIME = 1e-9ms

time

+
+ +
+ +++++ + + + + + + +

averageIsi

The average interspike interval

time

+

   averageIsi = 1 / averageRate

+
+ +
+ ++++ + + + + + +

spikeTarget

The target of the spikes, i.e. the synapse

+
+ +
+ +++++ + + + + + + +

synapse

baseSynapse

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

isi

The interval until the next spike

time

tnextIdeal

time

tnextUsed

time

tsince

Time since the last spike was emitted (from baseVoltageDepPointCurrentSpiking)

time

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

spike

Port on which spikes are emitted

Direction: out

spike

Port on which spikes are emitted (from baseVoltageDepPointCurrentSpiking)

Direction: out

+
+ +
+
+
Structure

WITH this AS a

+
+

WITH spikeTarget AS b

+
+

CHILD INSTANCE: synapse

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnextIdeal: time  (exposed as tnextIdeal)

+
+

tnextUsed: time  (exposed as tnextUsed)

+
+

isi: time  (exposed as isi)

+
+
On Start

tsince = 0

+
+

isi = - averageIsi * log(random(1))

+
+

tnextIdeal = isi

+
+

tnextUsed = isi

+
+
On Conditions

IF t > tnextUsed THEN

+
+

   tsince = 0

+
+

   isi = - averageIsi * log(1 - random(1))

+
+

   tnextIdeal = (tnextIdeal+isi)

+
+

   tnextUsed = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t )

+
+

   EVENT OUT on port: spike

+
+
Derived Variables

iSyn = synapse->i

+
+

i = weight * iSyn (exposed as i)

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnextUsed /dt = 0

+
+

d tnextIdeal /dt = 0

+
+
+
+ +
+
<xs:complexType name="PoissonFiringSynapse">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="averageRate" type="Nml2Quantity_pertime" use="required"/>
+      <xs:attribute name="synapse" type="xs:string" use="required"/>
+      <xs:attribute name="spikeTarget" type="xs:string" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import PoissonFiringSynapse
+
+variable = PoissonFiringSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    average_rate: 'a Nml2Quantity_pertime (required)' = None,
+    synapse: 'a string (required)' = None,
+    spike_target: 'a string (required)' = None,
+)
+
+
+
+ +
+
<poissonFiringSynapse id="poissonFiringSyn" averageRate="10 Hz" synapse="synInput" spikeTarget="./synInput"/>
+
+
+
+
+
+
+

transientPoissonFiringSynapse#

+

extends baseVoltageDepPointCurrentSpiking

+

Poisson spike generator firing at averageRate after a delay and for a duration, connected to single synapse that is triggered every time a spike is generated, providing an input current. Similar to ComponentType poissonFiringSynapse.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

averageRate

per_time

delay

time

duration

time

+
+ +
+ +++++ + + + + + + + + + + +

SMALL_TIME = 1e-9ms

time

LONG_TIME = 1e9hour

time

+
+ +
+ +++++ + + + + + + +

averageIsi

time

+

   averageIsi = 1 / averageRate

+
+ +
+ ++++ + + + + + +

spikeTarget

+
+ +
+ +++++ + + + + + + +

synapse

baseSynapse

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

isi

time

tnextIdeal

time

tnextUsed

time

tsince

Time since the last spike was emitted (from baseVoltageDepPointCurrentSpiking)

time

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

spike

Port on which spikes are emitted

Direction: out

spike

Port on which spikes are emitted (from baseVoltageDepPointCurrentSpiking)

Direction: out

+
+ +
+
+
Structure

WITH this AS a

+
+

WITH spikeTarget AS b

+
+

CHILD INSTANCE: synapse

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnextIdeal: time  (exposed as tnextIdeal)

+
+

tnextUsed: time  (exposed as tnextUsed)

+
+

isi: time  (exposed as isi)

+
+
On Start

tsince = 0

+
+

isi = - averageIsi * log(1 - random(1)) +delay

+
+

tnextIdeal = isi

+
+

tnextUsed = isi

+
+
On Conditions

IF t > tnextUsed THEN

+
+

   tsince = 0

+
+

   isi = - averageIsi * log(1 - random(1))

+
+

   tnextIdeal = (tnextIdeal+isi) + H(((t+isi) - (delay+duration))/duration)*LONG_TIME

+
+

   tnextUsed = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t )

+
+

   EVENT OUT on port: spike

+
+
Derived Variables

iSyn = synapse->i

+
+

i = weight * iSyn (exposed as i)

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnextUsed /dt = 0

+
+

d tnextIdeal /dt = 0

+
+
+
+ +
+
<xs:complexType name="TransientPoissonFiringSynapse">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="averageRate" type="Nml2Quantity_pertime" use="required"/>
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="synapse" type="xs:string" use="required"/>
+      <xs:attribute name="spikeTarget" type="xs:string" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import TransientPoissonFiringSynapse
+
+variable = TransientPoissonFiringSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    average_rate: 'a Nml2Quantity_pertime (required)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    synapse: 'a string (required)' = None,
+    spike_target: 'a string (required)' = None,
+)
+
+
+
+ +
+
<transientPoissonFiringSynapse id="transPoissonFiringSyn" delay="50ms" duration="50ms" averageRate="300 Hz" synapse="synInputFast" spikeTarget="./synInputFast"/>
+
+
+
<transientPoissonFiringSynapse id="transPoissonFiringSyn2" delay="50ms" duration="500ms" averageRate="10 Hz" synapse="synInputFastTwo" spikeTarget="./synInputFastTwo"/>
+
+
+
+
+
+
+

timedSynapticInput#

+

extends baseVoltageDepPointCurrentSpiking

+

Spike array connected to a single synapse, producing a current triggered by each spike in the array.

+
+ +
+ ++++ + + + + + +

spikeTarget

+
+ +
+ +++++ + + + + + + +

synapse

baseSynapse

+
+ +
+ +++++ + + + + + + +

spikes

spike

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

tsince

Time since the last spike was emitted (from baseVoltageDepPointCurrentSpiking)

time

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+ +++++ + + + + + + + + + + +

in

This will receive events from the children

Direction: in

spike

Port on which spikes are emitted (from baseVoltageDepPointCurrentSpiking)

Direction: out

+
+ +
+
+
Structure

WITH this AS a

+
+

WITH spikeTarget AS b

+
+

CHILD INSTANCE: synapse

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

tsince: time  (exposed as tsince)

+
+
On Events

EVENT IN on port: in

+
+

   tsince = 0

+
+

   EVENT OUT on port: spike

+
+
Derived Variables

iSyn = synapse->i

+
+

i = weight * iSyn (exposed as i)

+
+
Time Derivatives

d tsince /dt = 1

+
+
+
+ +
+
<xs:complexType name="TimedSynapticInput">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="spike" type="Spike" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="synapse" type="NmlId" use="required"/>
+      <xs:attribute name="spikeTarget" type="xs:string" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import TimedSynapticInput
+
+variable = TimedSynapticInput(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    synapse: 'a NmlId (required)' = None,
+    spike_target: 'a string (required)' = None,
+    spikes: 'list of Spike(s) (optional)' = None,
+)
+
+
+
+ +
+
<timedSynapticInput id="synTrain" synapse="synInputFastTwo" spikeTarget="./synInputFastTwo">
+        <spike id="0" time="2 ms"/>
+        <spike id="1" time="15 ms"/>
+        <spike id="2" time="27 ms"/>
+        <spike id="3" time="40 ms"/>
+        <spike id="4" time="45 ms"/>
+        <spike id="5" time="50 ms"/>
+        <spike id="6" time="52 ms"/>
+        <spike id="7" time="54 ms"/>
+        <spike id="8" time="54.5 ms"/>
+        <spike id="9" time="54.6 ms"/>
+        <spike id="10" time="54.7 ms"/>
+        <spike id="11" time="54.8 ms"/>
+        <spike id="12" time="54.9 ms"/>
+        <spike id="13" time="55 ms"/>
+        <spike id="14" time="55.1 ms"/>
+        <spike id="15" time="55.2 ms"/>
+    </timedSynapticInput>
+
+
+
+
+
+
+

spikeArray#

+

extends baseSpikeSource

+

Set of spike ComponentTypes, each emitting one spike at a certain time. Can be used to feed a predetermined spike train into a cell.

+
+ +
+ +++++ + + + + + + +

spikes

spike

+
+ +
+ +++++ + + + + + + +

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + + + + + +

in

This will receive events from the children

Direction: in

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
State Variables

tsince: time  (exposed as tsince)

+
+
On Start

tsince = 0

+
+
On Events

EVENT IN on port: in

+
+

   tsince = 0

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+
+
+ +
+
<xs:complexType name="SpikeArray">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="spike" type="Spike" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeArray
+
+variable = SpikeArray(
+    id: 'a NonNegativeInteger (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    spikes: 'list of Spike(s) (optional)' = None,
+)
+
+
+
+ +
+
<spikeArray id="spkArr">
+      <spike id="0" time="50 ms"/>
+      <spike id="1" time="100 ms"/>
+      <spike id="2" time="150 ms"/>
+      <spike id="3" time="155 ms"/>
+      <spike id="4" time="250 ms"/>
+    </spikeArray>
+
+
+
+
+
+
+

spike#

+

extends baseSpikeSource

+

Emits a single spike at the specified time.

+
+ +
+ +++++ + + + + + + +

time

Time at which to emit one spike event

time

+
+ +
+ +++++ + + + + + + + + + + +

spiked

0 signals not yet spiked, 1 signals has spiked

Dimensionless

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + +

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
Structure

WITH this AS a

+
+

WITH parent AS b

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

tsince: time  (exposed as tsince)

+
+

spiked: Dimensionless  (exposed as spiked)

+
+
On Start

tsince = 0

+
+
On Conditions

IF (t >= time) AND (spiked = 0) THEN

+
+

   spiked = 1

+
+

   tsince = 0

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+
+
+ +
+
<xs:complexType name="Spike">
+  <xs:complexContent>
+    <xs:extension base="BaseNonNegativeIntegerId">
+      <xs:attribute name="time" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Spike
+
+variable = Spike(
+    id: 'a NonNegativeInteger (required)' = None,
+    time: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<spike id="0" time="50 ms"/>
+
+
+
<spike id="1" time="100 ms"/>
+
+
+
<spike id="2" time="150 ms"/>
+
+
+
+
+
+
+

pulseGenerator#

+

extends basePointCurrent

+

Generates a constant current pulse of a certain amplitude for a specified duration after a delay. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

amplitude

Amplitude of current pulse

current

delay

Delay before change in current. Current is zero prior to this.

time

duration

Duration for holding current at amplitude. Current is zero after delay + duration.

time

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

Note: this is not used here. Will be removed in future

Direction: in

+
+ +
+
+
State Variables

i: current  (exposed as i)

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   i = 0

+
+

IF t >= delay AND t < duration + delay THEN

+
+

   i = weight * amplitude

+
+

IF t >= duration + delay THEN

+
+

   i = 0

+
+
+
+ +
+
<xs:complexType name="PulseGenerator">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="amplitude" type="Nml2Quantity_current" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import PulseGenerator
+
+variable = PulseGenerator(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    amplitude: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+ +
+
<pulseGenerator id="pulseGen1" delay="50ms" duration="200ms" amplitude="0.0032nA"/>
+
+
+
<pulseGenerator id="pulseGen2" delay="400ms" duration="200ms" amplitude="0.0020nA"/>
+
+
+
<pulseGenerator id="pulseGen3" delay="700ms" duration="200ms" amplitude="0.0010nA"/>
+
+
+
+
+
+
+

compoundInput#

+

extends basePointCurrent

+

Generates a current which is the sum of all its child basePointCurrent element, e.g. can be a combination of pulseGenerator, sineGenerator elements producing a single i. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + +

currents

basePointCurrent

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

+
+ +
+
+
On Events

EVENT IN on port: in

+
+
Derived Variables

i_total = currents[*]->i(reduce method: add)

+
+

i = weight * i_total (exposed as i)

+
+
+
+ +
+
<xs:complexType name="CompoundInput">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="pulseGenerator" type="PulseGenerator" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="sineGenerator" type="SineGenerator" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="rampGenerator" type="RampGenerator" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import CompoundInput
+
+variable = CompoundInput(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    pulse_generators: 'list of PulseGenerator(s) (optional)' = None,
+    sine_generators: 'list of SineGenerator(s) (optional)' = None,
+    ramp_generators: 'list of RampGenerator(s) (optional)' = None,
+)
+
+
+
+ +
+
<compoundInput id="ci0">
+        <pulseGenerator id="pg1" delay="50ms" duration="200ms" amplitude=".8 nA"/>
+        <pulseGenerator id="pg2" delay="100ms" duration="100ms" amplitude=".4 nA"/>
+        <sineGenerator id="sg0" phase="0" delay="125ms" duration="50ms" amplitude=".4nA" period="25ms"/>
+    </compoundInput>
+
+
+
+
+
+
+

compoundInputDL#

+

extends basePointCurrentDL

+

Generates a current which is the sum of all its child basePointCurrentDL elements, e.g. can be a combination of pulseGeneratorDL, sineGeneratorDL elements producing a single i. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + +

currents

basePointCurrentDL

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType (from basePointCurrentDL)

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

+
+ +
+
+
On Events

EVENT IN on port: in

+
+
Derived Variables

I_total = currents[*]->I(reduce method: add)

+
+

I = weight * I_total (exposed as I)

+
+
+
+ +
+
<xs:complexType name="CompoundInputDL">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="pulseGeneratorDL" type="PulseGeneratorDL" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="sineGeneratorDL" type="SineGeneratorDL" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="rampGeneratorDL" type="RampGeneratorDL" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import CompoundInputDL
+
+variable = CompoundInputDL(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    pulse_generator_dls: 'list of PulseGeneratorDL(s) (optional)' = None,
+    sine_generator_dls: 'list of SineGeneratorDL(s) (optional)' = None,
+    ramp_generator_dls: 'list of RampGeneratorDL(s) (optional)' = None,
+)
+
+
+
+
+
+
+

pulseGeneratorDL#

+

extends basePointCurrentDL

+

Dimensionless equivalent of pulseGenerator. Generates a constant current pulse of a certain amplitude for a specified duration after a delay. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

amplitude

Amplitude of current pulse

Dimensionless

delay

Delay before change in current. Current is zero prior to this.

time

duration

Duration for holding current at amplitude. Current is zero after delay + duration.

time

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType (from basePointCurrentDL)

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

+
+ +
+
+
State Variables

I: Dimensionless  (exposed as I)

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   I = 0

+
+

IF t >= delay AND t < duration + delay THEN

+
+

   I = weight * amplitude

+
+

IF t >= duration + delay THEN

+
+

   I = 0

+
+
+
+ +
+
<xs:complexType name="PulseGeneratorDL">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="amplitude" type="Nml2Quantity_none" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import PulseGeneratorDL
+
+variable = PulseGeneratorDL(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    amplitude: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+
+
+
+

sineGenerator#

+

extends basePointCurrent

+

Generates a sinusoidally varying current after a time delay, for a fixed duration. The period and maximum amplitude of the current can be set as well as the phase at which to start. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

amplitude

Maximum amplitude of current

current

delay

Delay before change in current. Current is zero prior to this.

time

duration

Duration for holding current at amplitude. Current is zero after delay + duration.

time

period

Time period of oscillation

time

phase

Phase (between 0 and 2*pi) at which to start the varying current (i.e. at time given by delay)

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

Direction: in

+
+ +
+
+
State Variables

i: current  (exposed as i)

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   i = 0

+
+

IF t >= delay AND t < duration+delay THEN

+
+

   i = weight * amplitude * sin(phase + (2 * 3.14159265 * (t-delay)/period) )

+
+

IF t >= duration+delay THEN

+
+

   i = 0

+
+
+
+ +
+
<xs:complexType name="SineGenerator">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="phase" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="amplitude" type="Nml2Quantity_current" use="required"/>
+      <xs:attribute name="period" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SineGenerator
+
+variable = SineGenerator(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    phase: 'a Nml2Quantity_none (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    amplitude: 'a Nml2Quantity_current (required)' = None,
+    period: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<sineGenerator id="sg0" phase="0" delay="50ms" duration="200ms" amplitude="1.4nA" period="50ms"/>
+
+
+
<sineGenerator id="sg0" phase="0" delay="125ms" duration="50ms" amplitude=".4nA" period="25ms"/>
+
+
+
+
+
+
+

sineGeneratorDL#

+

extends basePointCurrentDL

+

Dimensionless equivalent of sineGenerator. Generates a sinusoidally varying current after a time delay, for a fixed duration. The period and maximum amplitude of the current can be set as well as the phase at which to start. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

amplitude

Maximum amplitude of current

Dimensionless

delay

Delay before change in current. Current is zero prior to this.

time

duration

Duration for holding current at amplitude. Current is zero after delay + duration.

time

period

Time period of oscillation

time

phase

Phase (between 0 and 2*pi) at which to start the varying current (i.e. at time given by delay)

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType (from basePointCurrentDL)

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

Direction: in

+
+ +
+
+
State Variables

I: Dimensionless  (exposed as I)

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   I = 0

+
+

IF t >= delay AND t < duration+delay THEN

+
+

   I = weight * amplitude * sin(phase + (2 * 3.14159265 * (t-delay)/period) )

+
+

IF t >= duration+delay THEN

+
+

   I = 0

+
+
+
+ +
+
<xs:complexType name="SineGeneratorDL">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="phase" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="amplitude" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="period" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SineGeneratorDL
+
+variable = SineGeneratorDL(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    phase: 'a Nml2Quantity_none (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    amplitude: 'a Nml2Quantity_current (required)' = None,
+    period: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+
+
+
+

rampGenerator#

+

extends basePointCurrent

+

Generates a ramping current after a time delay, for a fixed duration. During this time the current steadily changes from startAmplitude to finishAmplitude. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

baselineAmplitude

Amplitude of current before time delay, and after time delay + duration

current

delay

Delay before change in current. Current is baselineAmplitude prior to this.

time

duration

Duration for holding current at amplitude. Current is baselineAmplitude after delay + duration.

time

finishAmplitude

Amplitude of linearly varying current at time delay + duration

current

startAmplitude

Amplitude of linearly varying current at time delay

current

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

Direction: in

+
+ +
+
+
State Variables

i: current  (exposed as i)

+
+
On Start

i = baselineAmplitude

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   i = weight * baselineAmplitude

+
+

IF t >= delay AND t < duration+delay THEN

+
+

   i = weight * (startAmplitude + (finishAmplitude - startAmplitude) * (t - delay) / (duration))

+
+

IF t >= duration+delay THEN

+
+

   i = weight * baselineAmplitude

+
+
+
+ +
+
<xs:complexType name="RampGenerator">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="startAmplitude" type="Nml2Quantity_current" use="required"/>
+      <xs:attribute name="finishAmplitude" type="Nml2Quantity_current" use="required"/>
+      <xs:attribute name="baselineAmplitude" type="Nml2Quantity_current" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import RampGenerator
+
+variable = RampGenerator(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    start_amplitude: 'a Nml2Quantity_current (required)' = None,
+    finish_amplitude: 'a Nml2Quantity_current (required)' = None,
+    baseline_amplitude: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+ +
+
<rampGenerator id="rg0" delay="50ms" duration="200ms" startAmplitude="0.5nA" finishAmplitude="4nA" baselineAmplitude="0nA"/>
+
+
+
+
+
+
+

rampGeneratorDL#

+

extends basePointCurrentDL

+

Dimensionless equivalent of rampGenerator. Generates a ramping current after a time delay, for a fixed duration. During this time the dimensionless current steadily changes from startAmplitude to finishAmplitude. Scaled by weight, if set.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

baselineAmplitude

Amplitude of current before time delay, and after time delay + duration

Dimensionless

delay

Delay before change in current. Current is baselineAmplitude prior to this.

time

duration

Duration for holding current at amplitude. Current is baselineAmplitude after delay + duration.

time

finishAmplitude

Amplitude of linearly varying current at time delay + duration

Dimensionless

startAmplitude

Amplitude of linearly varying current at time delay

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType (from basePointCurrentDL)

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

Direction: in

+
+ +
+
+
State Variables

I: Dimensionless  (exposed as I)

+
+
On Start

I = baselineAmplitude

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   I = weight * baselineAmplitude

+
+

IF t >= delay AND t < duration+delay THEN

+
+

   I = weight * (startAmplitude + (finishAmplitude - startAmplitude) * (t - delay) / (duration))

+
+

IF t >= duration+delay THEN

+
+

   I = weight * baselineAmplitude

+
+
+
+ +
+
<xs:complexType name="RampGeneratorDL">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="startAmplitude" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="finishAmplitude" type="Nml2Quantity_none" use="required"/>
+      <xs:attribute name="baselineAmplitude" type="Nml2Quantity_none" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import RampGeneratorDL
+
+variable = RampGeneratorDL(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    start_amplitude: 'a Nml2Quantity_current (required)' = None,
+    finish_amplitude: 'a Nml2Quantity_current (required)' = None,
+    baseline_amplitude: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+
+
+
+

voltageClamp#

+

extends baseVoltageDepPointCurrent

+

Voltage clamp. Applies a variable current i to try to keep parent at targetVoltage. Not yet fully tested!!! Consider using voltageClampTriple!!

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

delay

Delay before change in current. Current is zero prior to this.

time

duration

Duration for attempting to keep parent at targetVoltage. Current is zero after delay + duration.

time

simpleSeriesResistance

Current will be calculated by the difference in voltage between the target and parent, divided by this value

resistance

targetVoltage

Current will be applied to try to get parent to this target voltage

voltage

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+ +++++ + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

+
+ +
+
+
State Variables

i: current  (exposed as i)

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF t < delay THEN

+
+

   i = 0

+
+

IF t >= delay THEN

+
+

   i = weight * (targetVoltage - v) / simpleSeriesResistance

+
+

IF t > duration + delay THEN

+
+

   i = 0

+
+
+
+ +
+
<xs:complexType name="VoltageClamp">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="targetVoltage" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="simpleSeriesResistance" type="Nml2Quantity_resistance" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import VoltageClamp
+
+variable = VoltageClamp(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    target_voltage: 'a Nml2Quantity_voltage (required)' = None,
+    simple_series_resistance: 'a Nml2Quantity_resistance (required)' = None,
+)
+
+
+
+
+
+
+

voltageClampTriple#

+

extends baseVoltageDepPointCurrent

+

Voltage clamp with 3 clamp levels. Applies a variable current i ( through simpleSeriesResistance ) to try to keep parent cell at conditioningVoltage until time delay, testingVoltage until delay + duration, and returnVoltage afterwards. Only enabled if active = 1.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

active

Whether the voltage clamp is active (1) or inactive (0).

Dimensionless

conditioningVoltage

Target voltage before time delay

voltage

delay

Delay before switching from conditioningVoltage to testingVoltage.

time

duration

Duration to hold at testingVoltage.

time

returnVoltage

Target voltage after time duration

voltage

simpleSeriesResistance

Current will be calculated by the difference in voltage between the target and parent, divided by this value

resistance

testingVoltage

Target voltage between times delay and delay + duration

voltage

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrent)

voltage

+
+ +
+ +++++ + + + + + + +

in

Note this is not used here. Will be removed in future

Direction: in

+
+ +
+
+
State Variables

i: current  (exposed as i)

+
+
On Events

EVENT IN on port: in

+
+
On Conditions

IF active = 1 AND t < delay THEN

+
+

   i = weight * (conditioningVoltage - v) / simpleSeriesResistance

+
+

IF active = 1 AND t >= delay THEN

+
+

   i = weight * (testingVoltage - v) / simpleSeriesResistance

+
+

IF active = 1 AND t > duration + delay THEN

+
+

   i = weight * (returnVoltage - v) / simpleSeriesResistance

+
+
+
+ +
+
<xs:complexType name="VoltageClampTriple">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="active" type="ZeroOrOne" use="required"/>
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="conditioningVoltage" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="testingVoltage" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="returnVoltage" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="simpleSeriesResistance" type="Nml2Quantity_resistance" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import VoltageClampTriple
+
+variable = VoltageClampTriple(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    active: 'a ZeroOrOne (required)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    conditioning_voltage: 'a Nml2Quantity_voltage (required)' = None,
+    testing_voltage: 'a Nml2Quantity_voltage (required)' = None,
+    return_voltage: 'a Nml2Quantity_voltage (required)' = None,
+    simple_series_resistance: 'a Nml2Quantity_resistance (required)' = None,
+)
+
+
+
+ +
+
<voltageClampTriple id="vClamp0" active="1" delay="50ms" duration="200ms" conditioningVoltage="-70mV" testingVoltage="-50mV" returnVoltage="-70mV" simpleSeriesResistance="1e6ohm"/>
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Networks.html b/Userdocs/Schemas/Networks.html new file mode 100644 index 00000000..73ef3271 --- /dev/null +++ b/Userdocs/Schemas/Networks.html @@ -0,0 +1,2994 @@ + + + + + + + + + + + Networks — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Networks#

+

Network descriptions for NeuroML 2. Describes network elements containing populations ( potentially of type populationList, and so specifying a list of cell locations ), projections ( i.e. lists of connections ) and inputs.

+
+

Original ComponentType definitions: Networks.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

network#

+

extends baseStandalone

+

Network containing: populations ( potentially of type populationList, and so specifying a list of cell locations ); projections ( with lists of connections ) and/or explicitConnections; and inputLists ( with lists of inputs ) and/or explicitInputs. Note: often in NeuroML this will be of type networkWithTemperature if there are temperature dependent elements ( e.g. ion channels ).

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

regions

region

populations

basePopulation

projections

projection

synapticConnections

explicitConnection

electricalProjection

electricalProjection

continuousProjection

continuousProjection

explicitInputs

explicitInput

inputs

inputList

+
+ +
+
<xs:complexType name="Network">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:sequence>
+        <xs:element name="space" type="Space" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="region" type="Region" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="extracellularProperties" type="ExtracellularPropertiesLocal" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="population" type="Population" maxOccurs="unbounded"/>
+        <xs:element name="cellSet" type="CellSet" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="synapticConnection" type="SynapticConnection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="projection" type="Projection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="electricalProjection" type="ElectricalProjection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="continuousProjection" type="ContinuousProjection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="explicitInput" type="ExplicitInput" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="inputList" type="InputList" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="type" type="networkTypes" use="optional"/>
+      <xs:attribute name="temperature" type="Nml2Quantity_temperature" use="optional"/>
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Network
+
+variable = Network(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    type: 'a networkTypes (optional)' = None,
+    temperature: 'a Nml2Quantity_temperature (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    spaces: 'list of Space(s) (optional)' = None,
+    regions: 'list of Region(s) (optional)' = None,
+    extracellular_properties: 'list of ExtracellularPropertiesLocal(s) (optional)' = None,
+    populations: 'list of Population(s) (required)' = None,
+    cell_sets: 'list of CellSet(s) (optional)' = None,
+    synaptic_connections: 'list of SynapticConnection(s) (optional)' = None,
+    projections: 'list of Projection(s) (optional)' = None,
+    electrical_projections: 'list of ElectricalProjection(s) (optional)' = None,
+    continuous_projections: 'list of ContinuousProjection(s) (optional)' = None,
+    explicit_inputs: 'list of ExplicitInput(s) (optional)' = None,
+    input_lists: 'list of InputList(s) (optional)' = None,
+)
+
+
+
+ +
+
<network id="net1">
+        <population id="iafPop1" component="iaf" size="1"/>
+        <population id="iafPop2" component="iaf" size="1"/>
+        <population id="iafPop3" component="iaf" size="1"/>
+        <continuousProjection id="testLinearGradedConn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop2">
+            <continuousConnection id="0" preCell="0" postCell="0" preComponent="silent1" postComponent="gs1"/>
+        </continuousProjection>
+        <continuousProjection id="testGradedConn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop3">
+            <continuousConnection id="0" preCell="0" postCell="0" preComponent="silent2" postComponent="gs2"/>
+        </continuousProjection>
+        <explicitInput target="iafPop1[0]" input="pulseGen1" destination="synapses"/>
+        <explicitInput target="iafPop1[0]" input="pulseGen2" destination="synapses"/>
+        <explicitInput target="iafPop1[0]" input="pulseGen3" destination="synapses"/>
+    </network>
+
+
+
<network id="net2">
+        <population id="hhPop1" component="hhcell" size="1" type="populationList">
+            <instance id="0">
+                <location x="0" y="0" z="0"/>
+            </instance>
+        </population>
+        <population id="hhPop2" component="hhcell" size="1" type="populationList">
+            <instance id="0">
+                <location x="100" y="0" z="0"/>
+            </instance>
+        </population>
+        <continuousProjection id="testGradedConn" presynapticPopulation="hhPop1" postsynapticPopulation="hhPop2">
+            <continuousConnectionInstanceW id="0" preCell="../hhPop1/0/hhcell" postCell="../hhPop2/0/hhcell" preComponent="silent1" postComponent="gs1" weight="1"/>
+        </continuousProjection>
+        <inputList id="i1" component="pulseGen1" population="hhPop1">
+            <input id="0" target="../hhPop1/0/hhcell" destination="synapses"/>
+        </inputList>
+    </network>
+
+
+
<network id="PyrCellNet">   
+    
+        
+        <population id="Population1" component="PyrCell" extracellularProperties="extracellular" size="9"> 
+        </population>
+        <projection id="Proj1" presynapticPopulation="Population1" postsynapticPopulation="Population1" synapse="AMPA">
+           
+        </projection>
+    </network>
+
+
+
+
+
+
+

networkWithTemperature#

+

extends network

+

Same as network, but with an explicit temperature for temperature dependent elements ( e.g. ion channels ).

+
+ +
+ +++++ + + + + + + +

temperature

temperature

+
+
+
+
+

basePopulation#

+

extends baseStandalone

+

A population of multiple instances of a specific component, which anything which extends baseCell.

+
+ +
+ +++++ + + + + + + +

component

baseCell

+
+ +
+ +++++ + + + + + + + + + + +

notes

notes

annotation

annotation

+
+ +
+ +++++ + + + + + + +

property

property

+
+
+
+
+

population#

+

extends basePopulation

+

A population of components, with just one parameter for the size, i.e. number of components to create. Note: quite often this is used with type= populationList which means the size is determined by the number of instances ( with locations ) in the list. The size attribute is still set, and there will be a validation error if this does not match the number in the list.

+
+ +
+ +++++ + + + + + + +

size

Number of instances of this Component to create when the population is instantiated

Dimensionless

+
+ +
+
<xs:complexType name="Population">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:choice>
+        <xs:element name="layout" type="Layout" minOccurs="0"/>
+        <xs:element name="instance" type="Instance" maxOccurs="unbounded"/>
+      </xs:choice>
+      <xs:attribute name="component" type="NmlId" use="required"/>
+      <xs:attribute name="size" type="NonNegativeInteger" use="optional"/>
+      <xs:attribute name="type" type="populationTypes" use="optional"/>
+      <xs:attribute name="extracellularProperties" type="NmlId" use="optional"/>
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Population
+
+variable = Population(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    component: 'a NmlId (required)' = None,
+    size: 'a NonNegativeInteger (optional)' = None,
+    type: 'a populationTypes (optional)' = None,
+    extracellular_properties: 'a NmlId (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    layout: 'a Layout (optional)' = None,
+    instances: 'list of Instance(s) (required)' = None,
+)
+
+
+
+ +
+
<population id="iafPop1" component="iaf" size="1"/>
+
+
+
<population id="iafPop2" component="iaf" size="1"/>
+
+
+
<population id="iafPop3" component="iaf" size="1"/>
+
+
+
+
+
+
+

populationList#

+

extends basePopulation

+

An explicit list of instances ( with locations ) of components in the population.

+
+ +
+ ++++ + + + + + +

size

Note: the size of the populationList to create is set by the number of explicitly defined instances. The size attribute is still set, and there will be a validation error if this does not match the number in the list.

+
+ +
+ +++++ + + + + + + +

instances

instance

+
+
+
+
+

instance#

+

Specifies a single instance of a component in a population ( placed at location ).

+
+ +
+ +++++ + + + + + + +

location

location

+
+ +
+
<xs:complexType name="Instance">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:sequence>
+        <xs:element name="location" type="Location"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:nonNegativeInteger"/>
+      <xs:attribute name="i" type="xs:nonNegativeInteger"/>
+      <xs:attribute name="j" type="xs:nonNegativeInteger"/>
+      <xs:attribute name="k" type="xs:nonNegativeInteger"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Instance
+
+variable = Instance(
+    id: 'a nonNegativeInteger (optional)' = None,
+    i: 'a nonNegativeInteger (optional)' = None,
+    j: 'a nonNegativeInteger (optional)' = None,
+    k: 'a nonNegativeInteger (optional)' = None,
+    location: 'a Location (required)' = None,
+)
+
+
+
+ +
+
<instance id="0">
+                <location x="0" y="0" z="0"/>
+            </instance>
+
+
+
<instance id="0">
+                <location x="100" y="0" z="0"/>
+            </instance>
+
+
+
<instance id="0">
+                <location x="0" y="0" z="0"/>
+            </instance>
+
+
+
+
+
+
+

location#

+

Specifies the ( x, y, z ) location of a single instance of a component in a population.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

x

Dimensionless

y

Dimensionless

z

Dimensionless

+
+ +
+
<xs:complexType name="Location">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="x" type="xs:float" use="required"/>
+      <xs:attribute name="y" type="xs:float" use="required"/>
+      <xs:attribute name="z" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Location
+
+variable = Location(
+    x: 'a float (required)' = None,
+    y: 'a float (required)' = None,
+    z: 'a float (required)' = None,
+)
+
+
+
+ +
+
<location x="0" y="0" z="0"/>
+
+
+
<location x="100" y="0" z="0"/>
+
+
+
<location x="0" y="0" z="0"/>
+
+
+
+
+
+
+

region#

+

Initial attempt to specify 3D region for placing cells. Work in progress…

+
+ +
+ +++++ + + + + + + +

rectangularExtent

rectangularExtent

+
+ +
+
<xs:complexType name="Region">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="space" type="NmlId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Region
+
+variable = Region(
+    id: 'a NmlId (required)' = None,
+    spaces: 'a NmlId (optional)' = None,
+    anytypeobjs_=None,
+)
+
+
+
+
+
+
+

rectangularExtent#

+

For defining a 3D rectangular box.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

xLength

Dimensionless

xStart

Dimensionless

yLength

Dimensionless

yStart

Dimensionless

zLength

Dimensionless

zStart

Dimensionless

+
+
+
+
+

projection#

+

Projection from one population, presynapticPopulation to another, postsynapticPopulation, through synapse. Contains lists of connection or connectionWD elements.

+
+ +
+ ++++ + + + + + + + + +

presynapticPopulation

postsynapticPopulation

+
+ +
+ +++++ + + + + + + +

synapse

baseSynapse

+
+ +
+ +++++ + + + + + + + + + + +

connections

connection

connectionsWD

connectionWD

+
+ +
+
<xs:complexType name="Projection">
+  <xs:complexContent>
+    <xs:extension base="BaseProjection">
+      <xs:sequence>
+        <xs:element name="connection" type="Connection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="connectionWD" type="ConnectionWD" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="synapse" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Projection
+
+variable = Projection(
+    id: 'a NmlId (required)' = None,
+    presynaptic_population: 'a NmlId (required)' = None,
+    postsynaptic_population: 'a NmlId (required)' = None,
+    synapse: 'a NmlId (required)' = None,
+    connections: 'list of Connection(s) (optional)' = None,
+    connection_wds: 'list of ConnectionWD(s) (optional)' = None,
+)
+
+
+
+ +
+
<projection id="Proj1" presynapticPopulation="Population1" postsynapticPopulation="Population1" synapse="AMPA">
+           
+        </projection>
+
+
+
<projection id="internal1" presynapticPopulation="iafCells" postsynapticPopulation="iafCells" synapse="syn1">
+            <!--TODO: Fix! want to define synapse in here, so that multiple synapses per connection can be defined
+            <synapseComponent component="syn1"/>-->
+            
+            <connection id="0" preCellId="../iafCells/0/iaf" postCellId="../iafCells/1/iaf"/>
+        </projection>
+
+
+
<projection id="internal2" presynapticPopulation="iafCells" postsynapticPopulation="iafCells" synapse="syn2">
+            <connection id="0" preCellId="../iafCells/0/iaf" postCellId="../iafCells/2/iaf"/>
+        </projection>
+
+
+
+
+
+
+

explicitConnection#

+

Explicit event connection between components.

+
+ +
+ ++++ + + + + + +

targetPort

+
+ +
+ ++++ + + + + + + + + +

from

to

+
+
+
+
+

connection#

+

Event connection directly between named components, which gets processed via a new instance of a synapse component which is created on the target component. Normally contained inside a projection element.

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + +

destination

preFractionAlong

postFractionAlong

preSegmentId

postSegmentId

+
+ +
+ ++++ + + + + + + + + +

preCellId

postCellId

+
+ +
+
<xs:complexType name="Connection">
+  <xs:complexContent>
+    <xs:extension base="BaseConnectionOldFormat">
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Connection
+
+variable = Connection(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell_id: 'a Nml2PopulationReferencePath (required)' = None,
+    pre_segment_id: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell_id: 'a Nml2PopulationReferencePath (required)' = None,
+    post_segment_id: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+)
+
+
+
+ +
+
<connection id="0" preCellId="../iafCells/0/iaf" postCellId="../iafCells/1/iaf"/>
+
+
+
<connection id="0" preCellId="../iafCells/0/iaf" postCellId="../iafCells/2/iaf"/>
+
+
+
<connection id="0" preCellId="../pop0/0/MultiCompCell" postCellId="../pop0/1/MultiCompCell" preSegmentId="0" preFractionAlong="0.5" postSegmentId="0" postFractionAlong="0.5"/>
+
+
+
+
+
+
+

synapticConnection#

+

extends explicitConnection

+

Explicit event connection between named components, which gets processed via a new instance of a synapse component which is created on the target component.

+
+ +
+ ++++ + + + + + +

destination

+
+ +
+ ++++ + + + + + + + + +

from

to

+
+ +
+ +++++ + + + + + + +

synapse

baseSynapse

+
+ +
+
<xs:complexType name="SynapticConnection">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+      <xs:attribute name="from" type="Nml2PopulationReferencePath" use="required"/>
+      <xs:attribute name="to" type="Nml2PopulationReferencePath" use="required"/>
+      <xs:attribute name="synapse" type="NmlId" use="required"/>
+      <xs:attribute name="destination" type="NmlId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SynapticConnection
+
+variable = SynapticConnection(
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    from_: 'a Nml2PopulationReferencePath (required)' = None,
+    to: 'a Nml2PopulationReferencePath (required)' = None,
+    synapse: 'a NmlId (required)' = None,
+    destination: 'a NmlId (optional)' = None,
+)
+
+
+
+
+
+
+

synapticConnectionWD#

+

extends synapticConnection

+

Explicit event connection between named components, which gets processed via a new instance of a synapse component which is created on the target component, includes setting of weight and delay for the synaptic connection.

+
+ +
+ +++++ + + + + + + + + + + +

delay

time

weight

Dimensionless

+
+ +
+ ++++ + + + + + + + + +

from

to

+
+
+
+
+

connectionWD#

+

extends connection

+

Event connection between named components, which gets processed via a new instance of a synapse component which is created on the target component, includes setting of weight and delay for the synaptic connection.

+
+ +
+ +++++ + + + + + + + + + + +

delay

time

weight

Dimensionless

+
+ +
+ ++++ + + + + + + + + + + + + + + + + + +

destination

preFractionAlong

postFractionAlong

preSegmentId

postSegmentId

+
+ +
+ ++++ + + + + + + + + +

preCellId

postCellId

+
+ +
+
<xs:complexType name="ConnectionWD">
+  <xs:complexContent>
+    <xs:extension base="BaseConnectionOldFormat">
+      <xs:attribute name="weight" type="xs:float" use="required"/>
+      <xs:attribute name="delay" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ConnectionWD
+
+variable = ConnectionWD(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell_id: 'a Nml2PopulationReferencePath (required)' = None,
+    pre_segment_id: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell_id: 'a Nml2PopulationReferencePath (required)' = None,
+    post_segment_id: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    weight: 'a float (required)' = None,
+    delay: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<connectionWD id="0" preCellId="../pop_EIF_cond_exp_isfa_ista[0]" postCellId="../pop_target[0]" weight="0.01" delay="10ms"/>
+
+
+
<connectionWD id="0" preCellId="../pop_EIF_cond_alpha_isfa_ista[0]" postCellId="../pop_target[1]" weight="0.005" delay="20ms"/>
+
+
+
<connectionWD id="0" preCellId="../pop_IF_curr_alpha[0]" postCellId="../pop_target[2]" weight="1" delay="30ms"/>
+
+
+
+
+
+
+

electricalConnection#

+

To enable connections between populations through gap junctions.

+
+ +
+ +++++ + + + + + + +

synapse

gapJunction

+
+ +
+
<xs:complexType name="ElectricalConnection">
+  <xs:complexContent>
+    <xs:extension base="BaseConnectionNewFormat">
+      <xs:attribute name="synapse" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ElectricalConnection
+
+variable = ElectricalConnection(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell: 'a string (required)' = None,
+    pre_segment: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell: 'a string (required)' = None,
+    post_segment: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    synapse: 'a NmlId (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<electricalConnection id="0" preCell="0" postCell="0" synapse="gj1"/>
+
+
+
+
+
+
+

electricalConnectionInstance#

+

To enable connections between populations through gap junctions. Populations need to be of type populationList and contain instance and location elements.

+
+ +
+ ++++ + + + + + + + + + + + + + + +

preFractionAlong

postFractionAlong

preSegment

postSegment

+
+ +
+ ++++ + + + + + + + + +

preCell

postCell

+
+ +
+ +++++ + + + + + + +

synapse

gapJunction

+
+ +
+
<xs:complexType name="ElectricalConnectionInstance">
+  <xs:complexContent>
+    <xs:extension base="ElectricalConnection"/>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ElectricalConnectionInstance
+
+variable = ElectricalConnectionInstance(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell: 'a string (required)' = None,
+    pre_segment: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell: 'a string (required)' = None,
+    post_segment: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    synapse: 'a NmlId (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<electricalConnectionInstance id="0" preCell="../iafPop1/0/iaf" postCell="../iafPop2/0/iaf" preSegment="0" preFractionAlong="0.5" postSegment="0" postFractionAlong="0.5" synapse="gj1"/>
+
+
+
+
+
+
+

electricalConnectionInstanceW#

+

extends electricalConnectionInstance

+

To enable connections between populations through gap junctions. Populations need to be of type populationList and contain instance and location elements. Includes setting of weight for the connection.

+
+ +
+ +++++ + + + + + + +

weight

Dimensionless

+
+ +
+ ++++ + + + + + + + + + + + + + + +

preFractionAlong

postFractionAlong

preSegment

postSegment

+
+ +
+ ++++ + + + + + + + + +

preCell

postCell

+
+ +
+
<xs:complexType name="ElectricalConnectionInstanceW">
+  <xs:complexContent>
+    <xs:extension base="ElectricalConnectionInstance">
+      <xs:attribute name="weight" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ElectricalConnectionInstanceW
+
+variable = ElectricalConnectionInstanceW(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell: 'a string (required)' = None,
+    pre_segment: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell: 'a string (required)' = None,
+    post_segment: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    synapse: 'a NmlId (required)' = None,
+    weight: 'a float (required)' = None,
+)
+
+
+
+
+
+
+

electricalProjection#

+

A projection between presynapticPopulation to another postsynapticPopulation through gap junctions.

+
+ +
+ +++++ + + + + + + + + + + +

presynapticPopulation

population

postsynapticPopulation

population

+
+ +
+ +++++ + + + + + + + + + + +

connections

electricalConnection

connectionInstances

electricalConnectionInstance

+
+ +
+
<xs:complexType name="ElectricalProjection">
+  <xs:complexContent>
+    <xs:extension base="BaseProjection">
+      <xs:sequence>
+        <xs:element name="electricalConnection" type="ElectricalConnection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="electricalConnectionInstance" type="ElectricalConnectionInstance" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="electricalConnectionInstanceW" type="ElectricalConnectionInstanceW" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ElectricalProjection
+
+variable = ElectricalProjection(
+    id: 'a NmlId (required)' = None,
+    presynaptic_population: 'a NmlId (required)' = None,
+    postsynaptic_population: 'a NmlId (required)' = None,
+    electrical_connections: 'list of ElectricalConnection(s) (optional)' = None,
+    electrical_connection_instances: 'list of ElectricalConnectionInstance(s) (optional)' = None,
+    electrical_connection_instance_ws: 'list of ElectricalConnectionInstanceW(s) (optional)' = None,
+)
+
+
+
+ +
+
<electricalProjection id="testGJconn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop2">
+            <electricalConnectionInstance id="0" preCell="../iafPop1/0/iaf" postCell="../iafPop2/0/iaf" preSegment="0" preFractionAlong="0.5" postSegment="0" postFractionAlong="0.5" synapse="gj1"/>
+        </electricalProjection>
+
+
+
<electricalProjection id="testGJconn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop2">
+            <electricalConnection id="0" preCell="0" postCell="0" synapse="gj1"/>
+        </electricalProjection>
+
+
+
+
+
+
+

continuousConnection#

+

An instance of a connection in a continuousProjection between presynapticPopulation to another postsynapticPopulation through a preComponent at the start and postComponent at the end. Can be used for analog synapses.

+
+ +
+ +++++ + + + + + + + + + + +

preComponent

baseGradedSynapse

postComponent

baseGradedSynapse

+
+ +
+
<xs:complexType name="ContinuousConnection">
+  <xs:complexContent>
+    <xs:extension base="BaseConnectionNewFormat">
+      <xs:attribute name="preComponent" type="NmlId" use="required"/>
+      <xs:attribute name="postComponent" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ContinuousConnection
+
+variable = ContinuousConnection(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell: 'a string (required)' = None,
+    pre_segment: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell: 'a string (required)' = None,
+    post_segment: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    pre_component: 'a NmlId (required)' = None,
+    post_component: 'a NmlId (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<continuousConnection id="0" preCell="0" postCell="0" preComponent="silent1" postComponent="gs1"/>
+
+
+
<continuousConnection id="0" preCell="0" postCell="0" preComponent="silent2" postComponent="gs2"/>
+
+
+
+
+
+
+

continuousConnectionInstance#

+

An instance of a connection in a continuousProjection between presynapticPopulation to another postsynapticPopulation through a preComponent at the start and postComponent at the end. Populations need to be of type populationList and contain instance and location elements. Can be used for analog synapses.

+
+ +
+ ++++ + + + + + + + + + + + + + + +

preFractionAlong

postFractionAlong

preSegment

postSegment

+
+ +
+ ++++ + + + + + + + + +

preCell

postCell

+
+ +
+ +++++ + + + + + + + + + + +

preComponent

baseGradedSynapse

postComponent

baseGradedSynapse

+
+ +
+
<xs:complexType name="ContinuousConnectionInstance">
+  <xs:complexContent>
+    <xs:extension base="ContinuousConnection"/>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ContinuousConnectionInstance
+
+variable = ContinuousConnectionInstance(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell: 'a string (required)' = None,
+    pre_segment: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell: 'a string (required)' = None,
+    post_segment: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    pre_component: 'a NmlId (required)' = None,
+    post_component: 'a NmlId (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

continuousConnectionInstanceW#

+

extends continuousConnectionInstance

+

An instance of a connection in a continuousProjection between presynapticPopulation to another postsynapticPopulation through a preComponent at the start and postComponent at the end. Populations need to be of type populationList and contain instance and location elements. Can be used for analog synapses. Includes setting of weight for the connection.

+
+ +
+ +++++ + + + + + + +

weight

Dimensionless

+
+ +
+ ++++ + + + + + + + + + + + + + + +

preFractionAlong

postFractionAlong

preSegment

postSegment

+
+ +
+ ++++ + + + + + + + + +

preCell

postCell

+
+ +
+
<xs:complexType name="ContinuousConnectionInstanceW">
+  <xs:complexContent>
+    <xs:extension base="ContinuousConnectionInstance">
+      <xs:attribute name="weight" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ContinuousConnectionInstanceW
+
+variable = ContinuousConnectionInstanceW(
+    id: 'a NonNegativeInteger (required)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    pre_cell: 'a string (required)' = None,
+    pre_segment: 'a NonNegativeInteger (optional)' = '0',
+    pre_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    post_cell: 'a string (required)' = None,
+    post_segment: 'a NonNegativeInteger (optional)' = '0',
+    post_fraction_along: 'a ZeroToOne (optional)' = '0.5',
+    pre_component: 'a NmlId (required)' = None,
+    post_component: 'a NmlId (required)' = None,
+    weight: 'a float (required)' = None,
+)
+
+
+
+ +
+
<continuousConnectionInstanceW id="0" preCell="../hhPop1/0/hhcell" postCell="../hhPop2/0/hhcell" preComponent="silent1" postComponent="gs1" weight="1"/>
+
+
+
+
+
+
+

continuousProjection#

+

A projection between presynapticPopulation and postsynapticPopulation through components preComponent at the start and postComponent at the end of a continuousConnection or continuousConnectionInstance. Can be used for analog synapses.

+
+ +
+ +++++ + + + + + + + + + + +

presynapticPopulation

population

postsynapticPopulation

population

+
+ +
+ +++++ + + + + + + + + + + +

connections

continuousConnection

connectionInstances

continuousConnectionInstance

+
+ +
+
<xs:complexType name="ContinuousProjection">
+  <xs:complexContent>
+    <xs:extension base="BaseProjection">
+      <xs:sequence>
+        <xs:element name="continuousConnection" type="ContinuousConnection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="continuousConnectionInstance" type="ContinuousConnectionInstance" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="continuousConnectionInstanceW" type="ContinuousConnectionInstanceW" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ContinuousProjection
+
+variable = ContinuousProjection(
+    id: 'a NmlId (required)' = None,
+    presynaptic_population: 'a NmlId (required)' = None,
+    postsynaptic_population: 'a NmlId (required)' = None,
+    continuous_connections: 'list of ContinuousConnection(s) (optional)' = None,
+    continuous_connection_instances: 'list of ContinuousConnectionInstance(s) (optional)' = None,
+    continuous_connection_instance_ws: 'list of ContinuousConnectionInstanceW(s) (optional)' = None,
+)
+
+
+
+ +
+
<continuousProjection id="testLinearGradedConn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop2">
+            <continuousConnection id="0" preCell="0" postCell="0" preComponent="silent1" postComponent="gs1"/>
+        </continuousProjection>
+
+
+
<continuousProjection id="testGradedConn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop3">
+            <continuousConnection id="0" preCell="0" postCell="0" preComponent="silent2" postComponent="gs2"/>
+        </continuousProjection>
+
+
+
<continuousProjection id="testGradedConn" presynapticPopulation="hhPop1" postsynapticPopulation="hhPop2">
+            <continuousConnectionInstanceW id="0" preCell="../hhPop1/0/hhcell" postCell="../hhPop2/0/hhcell" preComponent="silent1" postComponent="gs1" weight="1"/>
+        </continuousProjection>
+
+
+
+
+
+
+

explicitInput#

+

An explicit input ( anything which extends basePointCurrent ) to a target cell in a population.

+
+ +
+ ++++ + + + + + + + + + + + +

destination

sourcePort

targetPort

+
+ +
+ ++++ + + + + + +

target

+
+ +
+ +++++ + + + + + + +

input

basePointCurrent

+
+ +
+
<xs:complexType name="ExplicitInput">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="target" type="Nml2PopulationReferencePath" use="required"/>
+      <xs:attribute name="input" type="NmlId" use="required"/>
+      <xs:attribute name="destination" type="NmlId"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ExplicitInput
+
+variable = ExplicitInput(
+    target: 'a Nml2PopulationReferencePath (required)' = None,
+    input: 'a NmlId (required)' = None,
+    destination: 'a NmlId (optional)' = None,
+)
+
+
+
+ +
+
<explicitInput target="iafPop1[0]" input="pulseGen1" destination="synapses"/>
+
+
+
<explicitInput target="iafPop1[0]" input="pulseGen2" destination="synapses"/>
+
+
+
<explicitInput target="iafPop1[0]" input="pulseGen3" destination="synapses"/>
+
+
+
+
+
+
+

inputList#

+

An explicit list of inputs to a population..

+
+ +
+ ++++ + + + + + +

population

+
+ +
+ +++++ + + + + + + +

component

basePointCurrent

+
+ +
+ +++++ + + + + + + +

inputs

input

+
+ +
+
<xs:complexType name="InputList">
+  <xs:complexContent>
+    <xs:extension base="Base">
+      <xs:sequence>
+        <xs:element name="input" type="Input" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="inputW" type="InputW" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="population" type="NmlId" use="required"/>
+      <xs:attribute name="component" type="NmlId" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import InputList
+
+variable = InputList(
+    id: 'a NonNegativeInteger (required)' = None,
+    populations: 'a NmlId (required)' = None,
+    component: 'a NmlId (required)' = None,
+    input: 'list of Input(s) (optional)' = None,
+    input_ws: 'list of InputW(s) (optional)' = None,
+)
+
+
+
+ +
+
<inputList id="i1" component="pulseGen1" population="hhPop1">
+            <input id="0" target="../hhPop1/0/hhcell" destination="synapses"/>
+        </inputList>
+
+
+
<inputList id="i1" component="pulseGen1" population="iafPop1">
+            <input id="0" target="../iafPop1/0/iaf" destination="synapses"/>
+        </inputList>
+
+
+
<inputList id="i2" component="pulseGen2" population="iafPop2">
+            <input id="0" target="../iafPop2/0/iaf" destination="synapses"/>
+        </inputList>
+
+
+
+
+
+
+

input#

+

Specifies a single input to a target, optionally giving the segmentId ( default 0 ) and fractionAlong the segment ( default 0.5 ).

+
+ +
+ ++++ + + + + + + + + + + + +

segmentId

Optional specification of the segment to target, default 0

fractionAlong

Optional specification of the fraction along the specified segment, default 0.5

destination

+
+ +
+ ++++ + + + + + +

target

+
+ +
+
<xs:complexType name="Input">
+  <xs:complexContent>
+    <xs:extension base="BaseNonNegativeIntegerId">
+      <xs:attribute name="target" type="Nml2PopulationReferencePath" use="required"/>
+      <xs:attribute name="destination" type="NmlId" use="required"/>
+      <xs:attribute name="segmentId" type="NonNegativeInteger"/>
+      <xs:attribute name="fractionAlong" type="ZeroToOne"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Input
+
+variable = Input(
+    id: 'a NonNegativeInteger (required)' = None,
+    target: 'a Nml2PopulationReferencePath (required)' = None,
+    destination: 'a NmlId (required)' = None,
+    segment_id: 'a NonNegativeInteger (optional)' = None,
+    fraction_along: 'a ZeroToOne (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<input id="0" target="../hhPop1/0/hhcell" destination="synapses"/>
+
+
+
<input id="0" target="../iafPop1/0/iaf" destination="synapses"/>
+
+
+
<input id="0" target="../iafPop2/0/iaf" destination="synapses"/>
+
+
+
+
+
+
+

inputW#

+

extends input

+

Specifies input lists. Can set weight to scale individual inputs.

+
+ +
+ +++++ + + + + + + +

weight

Dimensionless

+
+ +
+ ++++ + + + + + +

destination

+
+ +
+ ++++ + + + + + +

target

+
+ +
+
<xs:complexType name="InputW">
+  <xs:complexContent>
+    <xs:extension base="Input">
+      <xs:attribute name="weight" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import InputW
+
+variable = InputW(
+    id: 'a NonNegativeInteger (required)' = None,
+    target: 'a Nml2PopulationReferencePath (required)' = None,
+    destination: 'a NmlId (required)' = None,
+    segment_id: 'a NonNegativeInteger (optional)' = None,
+    fraction_along: 'a ZeroToOne (optional)' = None,
+    weight: 'a float (required)' = None,
+)
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/NeuroMLCoreCompTypes.html b/Userdocs/Schemas/NeuroMLCoreCompTypes.html new file mode 100644 index 00000000..0208cc1e --- /dev/null +++ b/Userdocs/Schemas/NeuroMLCoreCompTypes.html @@ -0,0 +1,1419 @@ + + + + + + + + + + + NeuroMLCoreCompTypes — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

NeuroMLCoreCompTypes#

+

Original ComponentType definitions: NeuroMLCoreCompTypes.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

notes#

+

Human readable notes/description for a Component.

+
+ +
+
<xs:simpleType name="Notes">
+  <xs:annotation>
+    <xs:documentation>Textual human readable notes related to the element in question. It's useful to put these into
+         the NeuroML files instead of XML comments, as the notes can be extracted and repeated in the files to which the NeuroML is mapped.
+            </xs:documentation>
+  </xs:annotation>
+  <xs:restriction base="xs:string"/>
+</xs:simpleType>
+
+
+
+ +
+
<notes>A Simple Spiking cell for testing purposes</notes>
+
+
+
<notes>Multicompartmental cell</notes>
+
+
+
<notes>Leak conductance</notes>
+
+
+
+
+
+
+

annotation#

+

A structured annotation containing metadata, specifically RDF or property elements.

+
+ +
+ +++++ + + + + + + +

rdf:RDF

rdf_RDF

+
+ +
+ +++++ + + + + + + +

property

property

+
+ +
+
<xs:complexType name="Annotation">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:sequence>
+        <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Annotation
+
+variable = Annotation(
+    anytypeobjs_=None,
+)
+
+
+
+ +
+
<annotation>
+            <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/">
+              <rdf:Description rdf:about="HippoCA1Cell">
+                <bqbiol:is>
+                  <rdf:Bag>
+                    
+                    <rdf:li rdf:resource="urn:miriam:neurondb:258"/>
+                  </rdf:Bag>
+                </bqbiol:is>
+              </rdf:Description>
+            </rdf:RDF>
+        </annotation>
+
+
+
+
+
+
+

property#

+

A property ( a tag and value pair ), which can be on any baseStandalone either as a direct child, or within an annotation. Generally something which helps the visual display or facilitates simulation of a Component, but is not a core physiological property. Common examples include: numberInternalDivisions, equivalent of nseg in NEURON; radius, for a radius to use in graphical displays for abstract cells ( i.e. without defined morphologies ); color, the color to use for a population or populationList of cells; recommended_dt_ms, the recommended timestep to use for simulating a network, recommended_duration_ms the recommended duration to use when running a network.

+
+ +
+ ++++ + + + + + + + + +

tag

Name of the property

value

Value of the property

+
+ +
+
<xs:complexType name="Property">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="tag" type="xs:string" use="required"/>
+      <xs:attribute name="value" type="xs:string" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Property
+
+variable = Property(
+    tag: 'a string (required)' = None,
+    value: 'a string (required)' = None,
+)
+
+
+
+ +
+
<property tag="numberInternalDivisions" value="9"/>
+
+
+
+
+
+
+

baseStandalone#

+

Base type of any Component which can have notes, annotation, or a property list.

+
+ +
+ +++++ + + + + + + + + + + +

notes

notes

annotation

annotation

+
+ +
+ +++++ + + + + + + +

property

property

+
+
+
+
+

rdf_RDF#

+

Structured block in an annotation based on RDF. See OpenSourceBrain/OSB_API.

+
+ +
+ ++++ + + + + + +

xmlns:rdf

+
+ +
+ +++++ + + + + + + +

rdf:Description

rdf_Description

+
+
+
+
+

rdf_Description#

+

Structured block in an annotation based on RDF.

+
+ +
+ ++++ + + + + + +

rdf:about

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

bqbiol:encodes

bqbiol_encodes

bqbiol:hasPart

bqbiol_hasPart

bqbiol:hasProperty

bqbiol_hasProperty

bqbiol:hasVersion

bqbiol_hasVersion

bqbiol:is

bqbiol_is

bqbiol:isDescribedBy

bqbiol_isDescribedBy

bqbiol:isEncodedBy

bqbiol_isEncodedBy

bqbiol:isHomologTo

bqbiol_isHomologTo

bqbiol:isPartOf

bqbiol_isPartOf

bqbiol:isPropertyOf

bqbiol_isPropertyOf

bqbiol:isVersionOf

bqbiol_isVersionOf

bqbiol:occursIn

bqbiol_occursIn

bqbiol:hasTaxon

bqbiol_hasTaxon

bqmodel:is

bqmodel_is

bqmodel:isDescribedBy

bqmodel_isDescribedBy

bqmodel:isDerivedFrom

bqmodel_isDerivedFrom

+
+
+
+
+

baseBqbiol#

+

Structured block in an annotation based on RDF.

+
+ +
+ +++++ + + + + + + +

rdf:Bag

rdf_Bag

+
+
+
+
+

bqbiol_encodes#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_hasPart#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_hasProperty#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_hasVersion#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_is#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_isDescribedBy#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_isEncodedBy#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_isHomologTo#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_isPartOf#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_isPropertyOf#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_isVersionOf#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+ +
+ ++++ + + + + + +

xmlns:bqbiol

+
+
+
+
+

bqbiol_occursIn#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqbiol_hasTaxon#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqmodel_is#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

bqmodel_isDescribedBy#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+ +
+ ++++ + + + + + +

xmlns:bqmodel

+
+
+
+
+

bqmodel_isDerivedFrom#

+

extends baseBqbiol

+

See http://co.mbine.org/standards/qualifiers.

+
+
+

rdf_Bag#

+

Structured block in an annotation based on RDF.

+
+ +
+ +++++ + + + + + + +

rdf:li

schema:rdf:li

+
+
+
+
+

rdf_li#

+

Structured block in an annotation based on RDF.

+
+ +
+ ++++ + + + + + +

rdf:resource

+
+
+
+
+

point3DWithDiam#

+

Base type for ComponentTypes which specify an ( x, y, z ) coordinate along with a diameter. Note: no dimension used in the attributes for these coordinates! These are assumed to have dimension micrometer ( 10^-6 m ). This is due to micrometers being the default option for the majority of neuronal morphology formats, and dimensions are omitted here to facilitate reading and writing of morphologies in NeuroML.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

diameter

Diameter of the ppoint. Note: no dimension used, see description of point3DWithDiam for details.

Dimensionless

x

x coordinate of the point. Note: no dimension used, see description of point3DWithDiam for details.

Dimensionless

y

y coordinate of the ppoint. Note: no dimension used, see description of point3DWithDiam for details.

Dimensionless

z

z coordinate of the ppoint. Note: no dimension used, see description of point3DWithDiam for details.

Dimensionless

+
+ +
+ +++++ + + + + + + +

MICRON = 1um

length

+
+ +
+ +++++ + + + + + + +

radius

A dimensional quantity given by half the _diameter.

length

+

   radius = MICRON * diameter / 2

+ +++++ + + + + + + +

xLength

A version of _x with dimension length.

length

+

   xLength = MICRON * x

+ +++++ + + + + + + +

yLength

A version of _y with dimension length.

length

+

   yLength = MICRON * y

+ +++++ + + + + + + +

zLength

A version of _z with dimension length.

length

+

   zLength = MICRON * z

+
+ +
+
<xs:complexType name="Point3DWithDiam">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="x" type="xs:double" use="required"/>
+      <xs:attribute name="y" type="xs:double" use="required"/>
+      <xs:attribute name="z" type="xs:double" use="required"/>
+      <xs:attribute name="diameter" type="DoubleGreaterThanZero" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import Point3DWithDiam
+
+variable = Point3DWithDiam(
+    x: 'a double (required)' = None,
+    y: 'a double (required)' = None,
+    z: 'a double (required)' = None,
+    diameter: 'a DoubleGreaterThanZero (required)' = None,
+)
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/NeuroMLCoreDimensions.html b/Userdocs/Schemas/NeuroMLCoreDimensions.html new file mode 100644 index 00000000..ef9ec56b --- /dev/null +++ b/Userdocs/Schemas/NeuroMLCoreDimensions.html @@ -0,0 +1,4134 @@ + + + + + + + + + + + NeuroMLCoreDimensions — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

NeuroMLCoreDimensions#

+

Original ComponentType definitions: NeuroMLCoreDimensions.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

Dimensions#

+
+

area#

+
+
+
+
+
+
+Dimensions
+

L2

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: cm2

  • +
  • Defined unit: m2

  • +
  • Defined unit: um2

  • +
+
+
+
+
+
+
+
+

capacitance#

+
+
+
+
+
+
+Dimensions
+

M-1 L-2 T4 I2

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: F

  • +
  • Defined unit: nF

  • +
  • Defined unit: pF

  • +
  • Defined unit: uF

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_capacitance">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(F|uF|nF|pF)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

charge#

+
+
+
+
+
+
+Dimensions
+

T1 I1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: C

  • +
  • Defined unit: e

  • +
+
+
+
+
+
+
+
+

charge_per_mole#

+
+
+
+
+
+
+Dimensions
+

T1 I1 N-1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+

concentration#

+
+
+
+
+
+
+Dimensions
+

L-3 N1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_concentration">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(mol_per_m3|mol_per_cm3|M|mM)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

conductance#

+
+
+
+
+
+
+Dimensions
+

M-1 L-2 T3 I2

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: S

  • +
  • Defined unit: mS

  • +
  • Defined unit: nS

  • +
  • Defined unit: pS

  • +
  • Defined unit: uS

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_conductance">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(S|mS|uS|nS|pS)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

conductanceDensity#

+
+
+
+
+
+
+Dimensions
+

M-1 L-4 T3 I2

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+

conductance_per_voltage#

+
+
+
+
+
+
+Dimensions
+

M-2 L-4 T6 I3

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_conductancePerVoltage">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(S_per_V|nS_per_mV)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

current#

+
+
+
+
+
+
+Dimensions
+

I1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: A

  • +
  • Defined unit: nA

  • +
  • Defined unit: pA

  • +
  • Defined unit: uA

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_current">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(A|uA|nA|pA)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

currentDensity#

+
+
+
+
+
+
+Dimensions
+

L-2 I1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+

idealGasConstantDims#

+
+
+
+
+
+
+Dimensions
+

M1 L2 T-2 K-1 N-1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+

length#

+
+
+
+
+
+
+Dimensions
+

L1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: cm

  • +
  • Defined unit: m

  • +
  • Defined unit: um

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_length">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(m|cm|um)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

per_time#

+
+
+
+
+
+
+Dimensions
+

T-1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_pertime">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(per_s|per_ms|Hz)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

per_voltage#

+
+
+
+
+
+
+Dimensions
+

M-1 L-2 T3 I1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+

permeability#

+
+
+
+
+
+
+Dimensions
+

L1 T-1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_permeability">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(m_per_s|um_per_ms|cm_per_s|cm_per_ms)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

resistance#

+
+
+
+
+
+
+Dimensions
+

M1 L2 T-3 I-2

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: Mohm

  • +
  • Defined unit: kohm

  • +
  • Defined unit: ohm

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_resistance">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(ohm|kohm|Mohm)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

resistivity#

+
+
+
+
+
+
+Dimensions
+

M2 L2 T-3 I-2

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+Schema
+
<xs:complexType name="Resistivity">
+  <xs:complexContent>
+    <xs:extension base="BaseWithoutId">
+      <xs:attribute name="value" type="Nml2Quantity_resistivity" use="required"/>
+      <xs:attribute name="segmentGroup" type="NmlId" use="optional" default="all"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+
+
+
+

rho_factor#

+
+
+
+
+
+
+Dimensions
+

L-1 T-1 I-1 N1

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_rhoFactor">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(mol_per_m_per_A_per_s|mol_per_cm_per_uA_per_ms)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

specificCapacitance#

+
+
+
+
+
+
+Dimensions
+

M-1 L-4 T4 I2

+
+
+
+
+
+
+
+Units
+ +
+
+
+
+
+
+
+

substance#

+
+
+
+
+
+
+Dimensions
+

N1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: mol

  • +
+
+
+
+
+
+
+
+

temperature#

+
+
+
+
+
+
+Dimensions
+

K1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: K

  • +
  • Defined unit: degC

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_temperature">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(degC)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

time#

+
+
+
+
+
+
+Dimensions
+

T1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: hour

  • +
  • Defined unit: min

  • +
  • Defined unit: ms

  • +
  • Defined unit: s

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_time">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(s|ms)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

voltage#

+
+
+
+
+
+
+Dimensions
+

M1 L2 T-3 I-1

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: V

  • +
  • Defined unit: mV

  • +
+
+
+
+
+
+
+
+Schema
+
<xs:simpleType name="Nml2Quantity_voltage">
+  <xs:restriction base="xs:string">
+    <xs:pattern value="-?([0-9]*(\.[0-9]+)?)([eE]-?[0-9]+)?[\s]*(V|mV)"/>
+  </xs:restriction>
+</xs:simpleType>
+
+
+
+
+
+
+
+
+
+

volume#

+
+
+
+
+
+
+Dimensions
+

L3

+
+
+
+
+
+
+
+Units
+
    +
  • Defined unit: cm3

  • +
  • Defined unit: litre

  • +
  • Defined unit: m3

  • +
  • Defined unit: um3

  • +
+
+
+
+
+
+
+
+
+

Units#

+
+

A#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: current

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 A = 1.00e+09 nA

  • +
  • 1 A = 1.00e+12 pA

  • +
  • 1 A = 1.00e+06 uA

  • +
+
+
+
+
+
+
+
+

A_per_m2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

C#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: charge

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 C = 6.24e+18 e

  • +
+
+
+
+
+
+
+
+

C_per_mol#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

F#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 F = 1.00e+09 nF

  • +
  • 1 F = 1.00e+12 pF

  • +
  • 1 F = 1.00e+06 uF

  • +
+
+
+
+
+
+
+
+

F_per_m2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

Hz#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

J_per_K_per_mol#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

K#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 K = -272.15 degC

  • +
+
+
+
+
+
+
+
+

M#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

Mohm#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 Mohm = 1000 kohm

  • +
  • 1 Mohm = 1.00e+06 ohm

  • +
+
+
+
+
+
+
+
+

S#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 S = 1000 mS

  • +
  • 1 S = 1.00e+09 nS

  • +
  • 1 S = 1.00e+12 pS

  • +
  • 1 S = 1.00e+06 uS

  • +
+
+
+
+
+
+
+
+

S_per_V#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

S_per_cm2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

S_per_m2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

V#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: voltage

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 V = 1000 mV

  • +
+
+
+
+
+
+
+
+

cm#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: length

  • +
  • Power of 10: -2

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 cm = 0.01 m

  • +
  • 1 cm = 10000 um

  • +
+
+
+
+
+
+
+
+

cm2#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: area

  • +
  • Power of 10: -4

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 cm2 = 0.0001 m2

  • +
  • 1 cm2 = 1.00e+08 um2

  • +
+
+
+
+
+
+
+
+

cm3#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: volume

  • +
  • Power of 10: -6

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 cm3 = 0.001 litre

  • +
  • 1 cm3 = 1e-06 m3

  • +
  • 1 cm3 = 1.00e+12 um3

  • +
+
+
+
+
+
+
+
+

cm_per_ms#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

cm_per_s#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

degC#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: temperature

  • +
  • Power of 10: 0

  • +
  • Offset: 273.15

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 degC = 274.15 K

  • +
+
+
+
+
+
+
+
+

e#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: charge

  • +
  • Power of 10: 0

  • +
  • Scale: 1.602176634e-19

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 e = 1.6022e-19 C

  • +
+
+
+
+
+
+
+
+

fJ_per_K_per_umol#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

hour#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: time

  • +
  • Power of 10: 0

  • +
  • Scale: 3600.0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 hour = 60 min

  • +
  • 1 hour = 3.60e+06 ms

  • +
  • 1 hour = 3600 s

  • +
+
+
+
+
+
+
+
+

kohm#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 kohm = 0.001 Mohm

  • +
  • 1 kohm = 1000 ohm

  • +
+
+
+
+
+
+
+
+

kohm_cm#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

litre#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: volume

  • +
  • Power of 10: -3

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 litre = 1000 cm3

  • +
  • 1 litre = 0.001 m3

  • +
  • 1 litre = 1.00e+15 um3

  • +
+
+
+
+
+
+
+
+

m#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: length

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 m = 100 cm

  • +
  • 1 m = 1.00e+06 um

  • +
+
+
+
+
+
+
+
+

m2#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: area

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 m2 = 10000 cm2

  • +
  • 1 m2 = 1.00e+12 um2

  • +
+
+
+
+
+
+
+
+

m3#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: volume

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 m3 = 1.00e+06 cm3

  • +
  • 1 m3 = 1000 litre

  • +
  • 1 m3 = 1.00e+18 um3

  • +
+
+
+
+
+
+
+
+

mA_per_cm2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

mM#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

mS#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 mS = 0.001 S

  • +
  • 1 mS = 1.00e+06 nS

  • +
  • 1 mS = 1.00e+09 pS

  • +
  • 1 mS = 1000 uS

  • +
+
+
+
+
+
+
+
+

mS_per_cm2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

mV#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: voltage

  • +
  • Power of 10: -3

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 mV = 0.001 V

  • +
+
+
+
+
+
+
+
+

m_per_s#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

min#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: time

  • +
  • Power of 10: 0

  • +
  • Scale: 60.0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 min = 0.016667 hour

  • +
  • 1 min = 6.00e+04 ms

  • +
  • 1 min = 60 s

  • +
+
+
+
+
+
+
+
+

mol#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+

mol_per_cm3#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 mol_per_cm3 = 1000 M

  • +
  • 1 mol_per_cm3 = 1.00e+06 mM

  • +
  • 1 mol_per_cm3 = 1.00e+06 mol_per_m3

  • +
+
+
+
+
+
+
+
+

mol_per_cm_per_uA_per_ms#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

mol_per_m3#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 mol_per_m3 = 0.001 M

  • +
  • 1 mol_per_m3 = 1 mM

  • +
  • 1 mol_per_m3 = 1e-06 mol_per_cm3

  • +
+
+
+
+
+
+
+
+

mol_per_m_per_A_per_s#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

ms#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: time

  • +
  • Power of 10: -3

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 ms = 2.7778e-07 hour

  • +
  • 1 ms = 1.6667e-05 min

  • +
  • 1 ms = 0.001 s

  • +
+
+
+
+
+
+
+
+

nA#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: current

  • +
  • Power of 10: -9

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 nA = 1e-09 A

  • +
  • 1 nA = 1000 pA

  • +
  • 1 nA = 0.001 uA

  • +
+
+
+
+
+
+
+
+

nA_ms_per_amol#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

nF#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 nF = 1e-09 F

  • +
  • 1 nF = 1000 pF

  • +
  • 1 nF = 0.001 uF

  • +
+
+
+
+
+
+
+
+

nS#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 nS = 1e-09 S

  • +
  • 1 nS = 1e-06 mS

  • +
  • 1 nS = 1000 pS

  • +
  • 1 nS = 0.001 uS

  • +
+
+
+
+
+
+
+
+

nS_per_mV#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

ohm#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 ohm = 1e-06 Mohm

  • +
  • 1 ohm = 0.001 kohm

  • +
+
+
+
+
+
+
+
+

ohm_cm#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

ohm_m#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

pA#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: current

  • +
  • Power of 10: -12

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 pA = 1e-12 A

  • +
  • 1 pA = 0.001 nA

  • +
  • 1 pA = 1e-06 uA

  • +
+
+
+
+
+
+
+
+

pC_per_umol#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

pF#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 pF = 1e-12 F

  • +
  • 1 pF = 0.001 nF

  • +
  • 1 pF = 1e-06 uF

  • +
+
+
+
+
+
+
+
+

pS#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 pS = 1e-12 S

  • +
  • 1 pS = 1e-09 mS

  • +
  • 1 pS = 0.001 nS

  • +
  • 1 pS = 1e-06 uS

  • +
+
+
+
+
+
+
+
+

per_V#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

per_hour#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: per_time

  • +
  • Power of 10: 0

  • +
  • Scale: 0.00027777777778

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 per_hour = 0.00027778 Hz

  • +
  • 1 per_hour = 0.016667 per_min

  • +
  • 1 per_hour = 2.7778e-07 per_ms

  • +
  • 1 per_hour = 0.00027778 per_s

  • +
+
+
+
+
+
+
+
+

per_mV#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 per_mV = 1000 per_V

  • +
+
+
+
+
+
+
+
+

per_min#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: per_time

  • +
  • Power of 10: 0

  • +
  • Scale: 0.01666666667

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 per_min = 0.016667 Hz

  • +
  • 1 per_min = 60 per_hour

  • +
  • 1 per_min = 1.6667e-05 per_ms

  • +
  • 1 per_min = 0.016667 per_s

  • +
+
+
+
+
+
+
+
+

per_ms#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

per_s#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

s#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: time

  • +
  • Power of 10: 0

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 s = 0.00027778 hour

  • +
  • 1 s = 0.016667 min

  • +
  • 1 s = 1000 ms

  • +
+
+
+
+
+
+
+
+

uA#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: current

  • +
  • Power of 10: -6

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 uA = 1e-06 A

  • +
  • 1 uA = 1000 nA

  • +
  • 1 uA = 1.00e+06 pA

  • +
+
+
+
+
+
+
+
+

uA_per_cm2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

uF#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 uF = 1e-06 F

  • +
  • 1 uF = 1000 nF

  • +
  • 1 uF = 1.00e+06 pF

  • +
+
+
+
+
+
+
+
+

uF_per_cm2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

uS#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+
    +
  • 1 uS = 1e-06 S

  • +
  • 1 uS = 0.001 mS

  • +
  • 1 uS = 1000 nS

  • +
  • 1 uS = 1.00e+06 pS

  • +
+
+
+
+
+
+
+
+

uS_per_cm2#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

um#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: length

  • +
  • Power of 10: -6

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 um = 0.0001 cm

  • +
  • 1 um = 1e-06 m

  • +
+
+
+
+
+
+
+
+

um2#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: area

  • +
  • Power of 10: -12

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 um2 = 1e-08 cm2

  • +
  • 1 um2 = 1e-12 m2

  • +
+
+
+
+
+
+
+
+

um3#

+
+
+
+
+
+
+Summary
+
    +
  • Dimension: volume

  • +
  • Power of 10: -18

  • +
+
+
+
+
+
+
+
+Conversions
+
    +
  • 1 um3 = 1e-12 cm3

  • +
  • 1 um3 = 1e-15 litre

  • +
  • 1 um3 = 1e-18 m3

  • +
+
+
+
+
+
+
+
+

um_per_ms#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+

umol_per_cm_per_nA_per_ms#

+
+
+
+
+
+
+Summary
+ +
+
+
+
+
+
+
+Conversions
+ +
+
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/PyNN.html b/Userdocs/Schemas/PyNN.html new file mode 100644 index 00000000..091c44ce --- /dev/null +++ b/Userdocs/Schemas/PyNN.html @@ -0,0 +1,3736 @@ + + + + + + + + + + + PyNN — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

PyNN#

+

A number of ComponentType description of PyNN standard cells. All of the cells extend basePyNNCell, and the synapses extend basePynnSynapse.

+
+

Original ComponentType definitions: PyNN.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

basePyNNCell#

+

extends baseCellMembPot

+

Base type of any PyNN standard cell model. Note: membrane potential v has dimensions voltage, but all other parameters are dimensionless. This is to facilitate translation to and from PyNN scripts in Python, where these parameters have implicit units, see http://neuralensemble.org/trac/PyNN/wiki/StandardModels.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

cm

Dimensionless

i_offset

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell

Dimensionless

v_init

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

MSEC = 1ms

time

MVOLT = 1mV

voltage

NFARAD = 1nF

capacitance

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

Direction: in

spike_in_I

Direction: in

+
+ +
+
<xs:complexType name="basePyNNCell">
+  <xs:complexContent>
+    <xs:extension base="BaseCell">
+      <xs:attribute name="cm" type="xs:float" use="required"/>
+      <xs:attribute name="i_offset" type="xs:float" use="required"/>
+      <xs:attribute name="tau_syn_E" type="xs:float" use="required"/>
+      <xs:attribute name="tau_syn_I" type="xs:float" use="required"/>
+      <xs:attribute name="v_init" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

basePyNNIaFCell#

+

extends basePyNNCell

+

Base type of any PyNN standard integrate and fire model.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

Dimensionless

tau_refrac

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

Dimensionless

v_rest

Dimensionless

v_thresh

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+
<xs:complexType name="basePyNNIaFCell">
+  <xs:complexContent>
+    <xs:extension base="basePyNNCell">
+      <xs:attribute name="tau_m" type="xs:float" use="required"/>
+      <xs:attribute name="tau_refrac" type="xs:float" use="required"/>
+      <xs:attribute name="v_reset" type="xs:float" use="required"/>
+      <xs:attribute name="v_rest" type="xs:float" use="required"/>
+      <xs:attribute name="v_thresh" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

basePyNNIaFCondCell#

+

extends basePyNNIaFCell

+

Base type of conductance based PyNN IaF cell models.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

e_rev_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell

Dimensionless

e_rev_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+
<xs:complexType name="basePyNNIaFCondCell">
+  <xs:complexContent>
+    <xs:extension base="basePyNNIaFCell">
+      <xs:attribute name="e_rev_E" type="xs:float" use="required"/>
+      <xs:attribute name="e_rev_I" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+
+
+
+

IF_curr_alpha#

+

extends basePyNNIaFCell

+

Leaky integrate and fire model with fixed threshold and alpha-function-shaped post-synaptic current.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

lastSpikeTime: time

+
+
On Start

v = v_init * MVOLT

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = v_reset * MVOLT

+
+

On Conditions

+
+

   IF t > lastSpikeTime + (tau_refrac*MSEC) THEN

+
+

    TRANSITION to REGIME integrating

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > v_thresh * MVOLT THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (MVOLT * ((i_offset/cm) + ((v_rest - (v/MVOLT)) / tau_m))/MSEC) + (iSyn / (cm * NFARAD))

+
+
+
+ +
+
<xs:complexType name="IF_curr_alpha">
+  <xs:complexContent>
+    <xs:extension base="basePyNNIaFCell">
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IF_curr_alpha
+
+variable = IF_curr_alpha(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    tau_m: 'a float (required)' = None,
+    tau_refrac: 'a float (required)' = None,
+    v_reset: 'a float (required)' = None,
+    v_rest: 'a float (required)' = None,
+    v_thresh: 'a float (required)' = None,
+)
+
+
+
+ +
+
<IF_curr_alpha id="IF_curr_alpha" cm="1.0" i_offset="0.9" tau_m="20.0" tau_refrac="10.0" tau_syn_E="0.5" tau_syn_I="0.5" v_init="-65" v_reset="-62.0" v_rest="-65.0" v_thresh="-52.0"/>
+
+
+
+
+
+
+

IF_curr_exp#

+

extends basePyNNIaFCell

+

Leaky integrate and fire model with fixed threshold and decaying-exponential post-synaptic current.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

lastSpikeTime: time

+
+
On Start

v = v_init * MVOLT

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = v_reset * MVOLT

+
+

On Conditions

+
+

   IF t > lastSpikeTime + (tau_refrac*MSEC) THEN

+
+

    TRANSITION to REGIME integrating

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > v_thresh * MVOLT THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (MVOLT * (((i_offset)/cm) + ((v_rest - (v/MVOLT)) / tau_m))/MSEC) + (iSyn / (cm * NFARAD))

+
+
+
+ +
+
<xs:complexType name="IF_curr_exp">
+  <xs:complexContent>
+    <xs:extension base="basePyNNIaFCell">
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IF_curr_exp
+
+variable = IF_curr_exp(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    tau_m: 'a float (required)' = None,
+    tau_refrac: 'a float (required)' = None,
+    v_reset: 'a float (required)' = None,
+    v_rest: 'a float (required)' = None,
+    v_thresh: 'a float (required)' = None,
+)
+
+
+
+ +
+
<IF_curr_exp id="IF_curr_exp" cm="1.0" i_offset="1.0" tau_m="20.0" tau_refrac="8.0" tau_syn_E="5.0" tau_syn_I="5.0" v_init="-65" v_reset="-70.0" v_rest="-65.0" v_thresh="-50.0"/>
+
+
+
+
+
+
+

IF_cond_alpha#

+

extends basePyNNIaFCondCell

+

Leaky integrate and fire model with fixed threshold and alpha-function-shaped post-synaptic conductance.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

e_rev_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

e_rev_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

lastSpikeTime: time

+
+
On Start

v = v_init * MVOLT

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = v_reset * MVOLT

+
+

On Conditions

+
+

   IF t > lastSpikeTime + (tau_refrac*MSEC) THEN

+
+

    TRANSITION to REGIME integrating

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > v_thresh * MVOLT THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (MVOLT * (((i_offset) / cm) + ((v_rest - (v / MVOLT)) / tau_m)) / MSEC) + (iSyn / (cm * NFARAD))

+
+
+
+ +
+
<xs:complexType name="IF_cond_alpha">
+  <xs:complexContent>
+    <xs:extension base="basePyNNIaFCondCell">
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IF_cond_alpha
+
+variable = IF_cond_alpha(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    tau_m: 'a float (required)' = None,
+    tau_refrac: 'a float (required)' = None,
+    v_reset: 'a float (required)' = None,
+    v_rest: 'a float (required)' = None,
+    v_thresh: 'a float (required)' = None,
+    e_rev_E: 'a float (required)' = None,
+    e_rev_I: 'a float (required)' = None,
+)
+
+
+
+ +
+
<IF_cond_alpha id="IF_cond_alpha" cm="1.0" e_rev_E="0.0" e_rev_I="-70.0" i_offset="0.9" tau_m="20.0" tau_refrac="5.0" tau_syn_E="0.3" tau_syn_I="0.5" v_init="-65" v_reset="-65.0" v_rest="-65.0" v_thresh="-50.0"/>
+
+
+
<IF_cond_alpha id="silent_cell" cm="1.0" e_rev_E="0.0" e_rev_I="-70.0" i_offset="0" tau_m="20.0" tau_refrac="5.0" tau_syn_E="5" tau_syn_I="10" v_init="-65" v_reset="-65.0" v_rest="-65.0" v_thresh="-50.0"/>
+
+
+
+
+
+
+

IF_cond_exp#

+

extends basePyNNIaFCondCell

+

Leaky integrate and fire model with fixed threshold and exponentially-decaying post-synaptic conductance.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

e_rev_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

e_rev_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

lastSpikeTime: time

+
+
On Start

v = v_init * MVOLT

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = v_reset * MVOLT

+
+

On Conditions

+
+

   IF t > lastSpikeTime + (tau_refrac*MSEC) THEN

+
+

    TRANSITION to REGIME integrating

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > v_thresh * MVOLT THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (MVOLT * (((i_offset)/cm) + ((v_rest - (v / MVOLT)) / tau_m)) / MSEC) + (iSyn / (cm * NFARAD))

+
+
+
+ +
+
<xs:complexType name="IF_cond_exp">
+  <xs:complexContent>
+    <xs:extension base="basePyNNIaFCondCell">
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import IF_cond_exp
+
+variable = IF_cond_exp(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    tau_m: 'a float (required)' = None,
+    tau_refrac: 'a float (required)' = None,
+    v_reset: 'a float (required)' = None,
+    v_rest: 'a float (required)' = None,
+    v_thresh: 'a float (required)' = None,
+    e_rev_E: 'a float (required)' = None,
+    e_rev_I: 'a float (required)' = None,
+)
+
+
+
+ +
+
<IF_cond_exp id="IF_cond_exp" cm="1.0" e_rev_E="0.0" e_rev_I="-70.0" i_offset="1.0" tau_m="20.0" tau_refrac="5.0" tau_syn_E="5.0" tau_syn_I="5.0" v_init="-65" v_reset="-68.0" v_rest="-65.0" v_thresh="-52.0"/>
+
+
+
+
+
+
+

EIF_cond_exp_isfa_ista#

+

extends basePyNNIaFCondCell

+

Adaptive exponential integrate and fire neuron according to Brette R and Gerstner W ( 2005 ) with exponentially-decaying post-synaptic conductance.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

a

Dimensionless

b

Dimensionless

cm

(from basePyNNCell)

Dimensionless

delta_T

Dimensionless

e_rev_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

e_rev_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_w

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_spike

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + +

eif_threshold

Dimensionless

+

   eif_threshold = v_spike * H(delta_T-1e-12) + v_thresh * H(-1*delta_T+1e-9)

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

w

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

w: Dimensionless  (exposed as w)

+
+

lastSpikeTime: time

+
+
On Start

v = v_init * MVOLT

+
+

w = 0

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+
Conditional Derived Variables

IF delta_T > 0 THEN

+
+

delta_I = delta_T * exp(((v / MVOLT) - v_thresh) / delta_T)

+
+

IF delta_T = 0 THEN

+
+

delta_I = 0

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = v_reset * MVOLT

+
+

   w = w+b

+
+

On Conditions

+
+

   IF t > lastSpikeTime + (tau_refrac*MSEC) THEN

+
+

    TRANSITION to REGIME integrating

+
+

Time Derivatives

+
+

   d w /dt = (1 / tau_w) * (a * ((v / MVOLT) - v_rest) - w) / MSEC

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > eif_threshold * MVOLT THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (MVOLT * ((-1 * ((v / MVOLT) - v_rest) + delta_I) / tau_m + (i_offset - w) / cm) / MSEC) + (iSyn / (cm * NFARAD))

+
+

   d w /dt = (1 / tau_w) * (a * ((v / MVOLT) - v_rest) - w) / MSEC

+
+
+
+ +
+
<xs:complexType name="EIF_cond_exp_isfa_ista">
+  <xs:complexContent>
+    <xs:extension base="basePyNNIaFCondCell">
+      <xs:attribute name="a" type="xs:float" use="required"/>
+      <xs:attribute name="b" type="xs:float" use="required"/>
+      <xs:attribute name="delta_T" type="xs:float" use="required"/>
+      <xs:attribute name="tau_w" type="xs:float" use="required"/>
+      <xs:attribute name="v_spike" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import EIF_cond_exp_isfa_ista
+
+variable = EIF_cond_exp_isfa_ista(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    tau_m: 'a float (required)' = None,
+    tau_refrac: 'a float (required)' = None,
+    v_reset: 'a float (required)' = None,
+    v_rest: 'a float (required)' = None,
+    v_thresh: 'a float (required)' = None,
+    e_rev_E: 'a float (required)' = None,
+    e_rev_I: 'a float (required)' = None,
+    a: 'a float (required)' = None,
+    b: 'a float (required)' = None,
+    delta_T: 'a float (required)' = None,
+    tau_w: 'a float (required)' = None,
+    v_spike: 'a float (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<EIF_cond_exp_isfa_ista id="EIF_cond_exp_isfa_ista" a="0.0" b="0.0805" cm="0.281" delta_T="2.0" e_rev_E="0.0" e_rev_I="-80.0" i_offset="0.6" tau_m="9.3667" tau_refrac="5" tau_syn_E="5.0" tau_syn_I="5.0" tau_w="144.0" v_init="-65" v_reset="-68.0" v_rest="-70.6" v_spike="-40.0" v_thresh="-52.0"/>
+
+
+
+
+
+
+

EIF_cond_alpha_isfa_ista#

+

extends basePyNNIaFCondCell

+

Adaptive exponential integrate and fire neuron according to Brette R and Gerstner W ( 2005 ) with alpha-function-shaped post-synaptic conductance.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

a

Dimensionless

b

Dimensionless

cm

(from basePyNNCell)

Dimensionless

delta_T

Dimensionless

e_rev_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

e_rev_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNIaFCondCell)

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_m

(from basePyNNIaFCell)

Dimensionless

tau_refrac

(from basePyNNIaFCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_w

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_reset

(from basePyNNIaFCell)

Dimensionless

v_rest

(from basePyNNIaFCell)

Dimensionless

v_spike

Dimensionless

v_thresh

(from basePyNNIaFCell)

Dimensionless

+
+ +
+ +++++ + + + + + + +

eif_threshold

Dimensionless

+

   eif_threshold = v_spike * H(delta_T-1e-12) + v_thresh * H(-1*delta_T+1e-9)

+
+ +
+ +++++ + + + + + + + + + + + + + + +

iSyn

(from basePyNNCell)

current

v

Membrane potential (from baseCellMembPot)

voltage

w

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

w: Dimensionless  (exposed as w)

+
+

lastSpikeTime: time

+
+
On Start

v = v_init * MVOLT

+
+

w = 0

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+
Conditional Derived Variables

IF delta_T > 0 THEN

+
+

delta_I = delta_T * exp(((v / MVOLT) - v_thresh) / delta_T)

+
+

IF delta_T = 0 THEN

+
+

delta_I = 0

+
+
Regime: refractory (initial)

On Entry

+
+

   lastSpikeTime = t

+
+

   v = v_reset * MVOLT

+
+

   w = w + b

+
+

On Conditions

+
+

   IF t > lastSpikeTime + (tau_refrac * MSEC) THEN

+
+

    TRANSITION to REGIME integrating

+
+

Time Derivatives

+
+

   d w /dt = (1 / tau_w) * (a * ((v / MVOLT) - v_rest) - w) / MSEC

+
+
Regime: integrating (initial)

On Conditions

+
+

   IF v > eif_threshold * MVOLT THEN

+
+

    EVENT OUT on port: spike

+
+

    TRANSITION to REGIME refractory

+
+

Time Derivatives

+
+

   d v /dt = (MVOLT * ((-1 * ( (v / MVOLT) - v_rest) + delta_I) / tau_m + (i_offset - w) / cm) / MSEC) + (iSyn / (cm * NFARAD))

+
+

   d w /dt = (1/ tau_w) * (a*((v/MVOLT)-v_rest) - w) /MSEC

+
+
+
+ +
+
<xs:complexType name="EIF_cond_alpha_isfa_ista">
+  <xs:complexContent>
+    <xs:extension base="EIF_cond_exp_isfa_ista">
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import EIF_cond_alpha_isfa_ista
+
+variable = EIF_cond_alpha_isfa_ista(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    tau_m: 'a float (required)' = None,
+    tau_refrac: 'a float (required)' = None,
+    v_reset: 'a float (required)' = None,
+    v_rest: 'a float (required)' = None,
+    v_thresh: 'a float (required)' = None,
+    e_rev_E: 'a float (required)' = None,
+    e_rev_I: 'a float (required)' = None,
+    a: 'a float (required)' = None,
+    b: 'a float (required)' = None,
+    delta_T: 'a float (required)' = None,
+    tau_w: 'a float (required)' = None,
+    v_spike: 'a float (required)' = None,
+)
+
+
+
+ +
+
<EIF_cond_alpha_isfa_ista id="EIF_cond_alpha_isfa_ista" a="0.0" b="0.0805" cm="0.281" delta_T="0" e_rev_E="0.0" e_rev_I="-80.0" i_offset="0.6" tau_m="9.3667" tau_refrac="5" tau_syn_E="5.0" tau_syn_I="5.0" tau_w="144.0" v_init="-65" v_reset="-68.0" v_rest="-70.6" v_spike="-40.0" v_thresh="-52.0"/>
+
+
+
+
+
+
+

HH_cond_exp#

+

extends basePyNNCell

+

Single-compartment Hodgkin-Huxley-type neuron with transient sodium and delayed-rectifier potassium currents using the ion channel models from Traub.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

cm

(from basePyNNCell)

Dimensionless

e_rev_E

Dimensionless

e_rev_I

Dimensionless

e_rev_K

Dimensionless

e_rev_Na

Dimensionless

e_rev_leak

Dimensionless

g_leak

Dimensionless

gbar_K

Dimensionless

gbar_Na

Dimensionless

i_offset

(from basePyNNCell)

Dimensionless

tau_syn_E

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

tau_syn_I

This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell (from basePyNNCell)

Dimensionless

v_init

(from basePyNNCell)

Dimensionless

v_offset

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

h

Dimensionless

iSyn

(from basePyNNCell)

current

m

Dimensionless

n

Dimensionless

v

Membrane potential (from baseCellMembPot)

voltage

+
+ +
+ +++++ + + + + + + + + + + + + + + +

spike

Spike event (from baseSpikingCell)

Direction: out

spike_in_E

(from basePyNNCell)

Direction: in

spike_in_I

(from basePyNNCell)

Direction: in

+
+ +
+ +++++ + + + + + + +

synapses

baseSynapse

+
+ +
+
+
State Variables

v: voltage  (exposed as v)

+
+

m: Dimensionless  (exposed as m)

+
+

h: Dimensionless  (exposed as h)

+
+

n: Dimensionless  (exposed as n)

+
+
On Start

v = v_init * MVOLT

+
+
Derived Variables

iSyn = synapses[*]->i(reduce method: add) (exposed as iSyn)

+
+

iLeak = g_leak * (e_rev_leak - (v / MVOLT))

+
+

iNa = gbar_Na * (m * m * m) * h * (e_rev_Na - (v / MVOLT))

+
+

iK = gbar_K * (n * n * n * n) * (e_rev_K - (v / MVOLT))

+
+

iMemb = iLeak + iNa + iK + i_offset

+
+

alpham = 0.32 * (13 - (v / MVOLT) + v_offset) / (exp((13 - (v / MVOLT) + v_offset) / 4.0) - 1)

+
+

betam = 0.28 * ((v / MVOLT) - v_offset - 40) / (exp(((v / MVOLT) - v_offset - 40) / 5.0) - 1)

+
+

alphah = 0.128 * exp((17 - (v / MVOLT) + v_offset) / 18.0)

+
+

betah = 4.0 / (1 + exp((40 - (v / MVOLT) + v_offset) / 5))

+
+

alphan = 0.032 * (15 - (v / MVOLT) + v_offset) / (exp((15 - (v / MVOLT) + v_offset) / 5) - 1)

+
+

betan = 0.5 * exp((10 - (v / MVOLT) + v_offset) / 40)

+
+
Time Derivatives

d v /dt = (MVOLT * (iMemb / cm) / MSEC) + (iSyn / (cm * NFARAD))

+
+

d m /dt = (alpham * (1 - m) - betam * m) / MSEC

+
+

d h /dt = (alphah * (1 - h) - betah * h) / MSEC

+
+

d n /dt = (alphan * (1 - n) - betan * n) / MSEC

+
+
+
+ +
+
<xs:complexType name="HH_cond_exp">
+  <xs:complexContent>
+    <xs:extension base="basePyNNCell">
+      <xs:attribute name="v_offset" type="xs:float" use="required"/>
+      <xs:attribute name="e_rev_E" type="xs:float" use="required"/>
+      <xs:attribute name="e_rev_I" type="xs:float" use="required"/>
+      <xs:attribute name="e_rev_K" type="xs:float" use="required"/>
+      <xs:attribute name="e_rev_Na" type="xs:float" use="required"/>
+      <xs:attribute name="e_rev_leak" type="xs:float" use="required"/>
+      <xs:attribute name="g_leak" type="xs:float" use="required"/>
+      <xs:attribute name="gbar_K" type="xs:float" use="required"/>
+      <xs:attribute name="gbar_Na" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import HH_cond_exp
+
+variable = HH_cond_exp(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    cm: 'a float (required)' = None,
+    i_offset: 'a float (required)' = None,
+    tau_syn_E: 'a float (required)' = None,
+    tau_syn_I: 'a float (required)' = None,
+    v_init: 'a float (required)' = None,
+    v_offset: 'a float (required)' = None,
+    e_rev_E: 'a float (required)' = None,
+    e_rev_I: 'a float (required)' = None,
+    e_rev_K: 'a float (required)' = None,
+    e_rev_Na: 'a float (required)' = None,
+    e_rev_leak: 'a float (required)' = None,
+    g_leak: 'a float (required)' = None,
+    gbar_K: 'a float (required)' = None,
+    gbar_Na: 'a float (required)' = None,
+)
+
+
+
+ +
+
<HH_cond_exp id="HH_cond_exp" cm="0.2" e_rev_E="0.0" e_rev_I="-80.0" e_rev_K="-90.0" e_rev_Na="50.0" e_rev_leak="-65.0" g_leak="0.01" gbar_K="6.0" gbar_Na="20.0" i_offset="0.2" tau_syn_E="0.2" tau_syn_I="2.0" v_init="-65" v_offset="-63.0"/>
+
+
+
+
+
+
+

basePynnSynapse#

+

extends baseVoltageDepSynapse

+

Base type for all PyNN synapses. Note, the current I produced is dimensionless, but it requires a membrane potential v with dimension voltage.

+
+ +
+ +++++ + + + + + + +

tau_syn

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

MSEC = 1ms

time

MVOLT = 1mV

voltage

NAMP = 1nA

current

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
<xs:complexType name="BasePynnSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+      <xs:attribute name="tau_syn" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BasePynnSynapse
+
+variable = BasePynnSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    tau_syn: 'a float (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

expCondSynapse#

+

extends basePynnSynapse

+

Conductance based synapse with instantaneous rise and single exponential decay ( with time constant tau_syn ).

+
+ +
+ +++++ + + + + + + + + + + +

e_rev

Dimensionless

tau_syn

(from basePynnSynapse)

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

g

Dimensionless

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

g: Dimensionless  (exposed as g)

+
+
On Events

EVENT IN on port: in

+
+

   g = g+weight

+
+
Derived Variables

i = g * (e_rev - (v/MVOLT)) * NAMP (exposed as i)

+
+
Time Derivatives

d g /dt = -g / (tau_syn*MSEC)

+
+
+
+ +
+
<xs:complexType name="ExpCondSynapse">
+  <xs:complexContent>
+    <xs:extension base="BasePynnSynapse">
+      <xs:attribute name="e_rev" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ExpCondSynapse
+
+variable = ExpCondSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    tau_syn: 'a float (required)' = None,
+    e_rev: 'a float (required)' = None,
+)
+
+
+
+ +
+
<expCondSynapse id="syn1" tau_syn="5" e_rev="0"/>
+
+
+
+
+
+
+

expCurrSynapse#

+

extends basePynnSynapse

+

Current based synapse with instantaneous rise and single exponential decay ( with time constant tau_syn ).

+
+ +
+ +++++ + + + + + + +

tau_syn

(from basePynnSynapse)

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

I: Dimensionless

+
+
On Events

EVENT IN on port: in

+
+

   I = I + weight

+
+
Derived Variables

i = I * NAMP (exposed as i)

+
+
Time Derivatives

d I /dt = -I / (tau_syn*MSEC)

+
+
+
+ +
+
<xs:complexType name="ExpCurrSynapse">
+  <xs:complexContent>
+    <xs:extension base="BasePynnSynapse">
+
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ExpCurrSynapse
+
+variable = ExpCurrSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    tau_syn: 'a float (required)' = None,
+)
+
+
+
+ +
+
<expCurrSynapse id="syn3" tau_syn="5"/>
+
+
+
+
+
+
+

alphaCondSynapse#

+

extends basePynnSynapse

+

Alpha synapse: rise time and decay time are both tau_syn. Conductance based synapse.

+
+ +
+ +++++ + + + + + + + + + + +

e_rev

Dimensionless

tau_syn

(from basePynnSynapse)

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

A

Dimensionless

g

Dimensionless

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

g: Dimensionless  (exposed as g)

+
+

A: Dimensionless  (exposed as A)

+
+
On Events

EVENT IN on port: in

+
+

   A = A + weight

+
+
Derived Variables

i = g * (e_rev - (v/MVOLT)) * NAMP (exposed as i)

+
+
Time Derivatives

d g /dt = (2.7182818A - g)/(tau_synMSEC)

+
+

d A /dt = -A /(tau_syn*MSEC)

+
+
+
+ +
+
<xs:complexType name="AlphaCondSynapse">
+  <xs:complexContent>
+    <xs:extension base="BasePynnSynapse">
+      <xs:attribute name="e_rev" type="xs:float" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import AlphaCondSynapse
+
+variable = AlphaCondSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    tau_syn: 'a float (required)' = None,
+    e_rev: 'a float (required)' = None,
+)
+
+
+
+ +
+
<alphaCondSynapse id="syn2" tau_syn="5" e_rev="0"/>
+
+
+
+
+
+
+

alphaCurrSynapse#

+

extends basePynnSynapse

+

Alpha synapse: rise time and decay time are both tau_syn. Current based synapse.

+
+ +
+ +++++ + + + + + + +

tau_syn

(from basePynnSynapse)

Dimensionless

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

A

current

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

I: Dimensionless

+
+

A: Dimensionless  (exposed as A)

+
+
On Events

EVENT IN on port: in

+
+

   A = A + weight

+
+
Derived Variables

i = I * NAMP (exposed as i)

+
+
Time Derivatives

d I /dt = (2.7182818A - I)/(tau_synMSEC)

+
+

d A /dt = -A /(tau_syn*MSEC)

+
+
+
+ +
+
<xs:complexType name="AlphaCurrSynapse">
+  <xs:complexContent>
+    <xs:extension base="BasePynnSynapse">
+
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import AlphaCurrSynapse
+
+variable = AlphaCurrSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    tau_syn: 'a float (required)' = None,
+)
+
+
+
+ +
+
<alphaCurrSynapse id="syn4" tau_syn="5"/>
+
+
+
+
+
+
+

SpikeSourcePoisson#

+

extends baseSpikeSource

+

Spike source, generating spikes according to a Poisson process.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

duration

time

rate

per_time

start

time

+
+ +
+ +++++ + + + + + + + + + + +

LONG_TIME = 1e9hour

time

SMALL_TIME = 1e-9ms

time

+
+ +
+ +++++ + + + + + + +

end

time

+

   end = start + duration

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

isi

time

tnextIdeal

time

tnextUsed

time

tsince

Time since the last spike was emitted (from baseSpikeSource)

time

+
+ +
+ +++++ + + + + + + + + + + +

in

Direction: in

spike

Port on which spikes are emitted (from baseSpikeSource)

Direction: out

+
+ +
+
+
State Variables

tsince: time  (exposed as tsince)

+
+

tnextIdeal: time  (exposed as tnextIdeal)

+
+

tnextUsed: time  (exposed as tnextUsed)

+
+

isi: time  (exposed as isi)

+
+
On Start

isi = start - log(random(1))/rate

+
+

tsince = 0

+
+

tnextIdeal = isi + H(((isi) - (start+duration))/duration)*LONG_TIME

+
+

tnextUsed = tnextIdeal

+
+
On Conditions

IF t > tnextUsed THEN

+
+

   isi = -1 * log(random(1))/rate

+
+

   tnextIdeal = (tnextIdeal+isi) + H(((tnextIdeal+isi) - (start+duration))/duration)*LONG_TIME

+
+

   tnextUsed = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t )

+
+

   tsince = 0

+
+

   EVENT OUT on port: spike

+
+
Time Derivatives

d tsince /dt = 1

+
+

d tnextUsed /dt = 0

+
+

d tnextIdeal /dt = 0

+
+
+
+ +
+
<xs:complexType name="SpikeSourcePoisson">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="start" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="duration" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="rate" type="Nml2Quantity_pertime" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SpikeSourcePoisson
+
+variable = SpikeSourcePoisson(
+    id: 'a NonNegativeInteger (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    start: 'a Nml2Quantity_time (required)' = None,
+    duration: 'a Nml2Quantity_time (required)' = None,
+    rate: 'a Nml2Quantity_pertime (required)' = None,
+)
+
+
+
+ +
+
<SpikeSourcePoisson id="spikes1" start="50ms" duration="400ms" rate="50Hz"/>
+
+
+
<SpikeSourcePoisson id="spikes2" start="50ms" duration="300ms" rate="80Hz"/>
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Simulation.html b/Userdocs/Schemas/Simulation.html new file mode 100644 index 00000000..abc0b5fc --- /dev/null +++ b/Userdocs/Schemas/Simulation.html @@ -0,0 +1,1101 @@ + + + + + + + + + + + Simulation — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Simulation

+ +
+ +
+
+ + + + +
+ +
+

Simulation#

+

Specification of the LEMS Simulation element which is normally used to define simulations of NeuroML2 files. Note: not actually part of NeuroML v2, but this is required by much of the NeuroML toolchain for defining Simulations ( which NeuroML model to use and how long to run for ), as well as what to Display and what to save in OutputFiles.

+
+

Original ComponentType definitions: Simulation.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

Simulation#

+

The main element in a LEMS Simulation file. Defines the length of simulation, the timestep ( dt ) step and an optional seed to use for stochastic elements, as well as Displays, OutputFiles and EventOutputFiles to record. Specifies a target component to run, usually the id of a network.

+
+ +
+ +++++ + + + + + + + + + + +

length

Duration of the simulation run

time

step

Time step (dt) to use in the simulation

time

+
+ +
+ ++++ + + + + + +

seed

The seed to use in the random number generator for stochastic entities

+
+ +
+ +++++ + + + + + + +

target

schema:component

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

metas

Meta

displays

Display

outputs

OutputFile

events

EventOutputFile

+
+ +
+
+
State Variables

t: time

+
+
+
+
+
+
+

Display#

+

Details of a display to generate ( usually a set of traces given by Lines in a newly opened window ) on completion of the simulation.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

timeScale

A scaling of the time axis, e.g. 1ms means display in milliseconds. Note: all quantities are recorded in SI units

time

xmax

The maximum value on the x axis (i.e time variable) of the display

Dimensionless

xmin

The minimum value on the x axis (i.e time variable) of the display

Dimensionless

ymax

The maximum value on the x axis of the display

Dimensionless

ymin

The minimum value on the y axis of the display

Dimensionless

+
+ +
+ ++++ + + + + + +

title

The title of the display, e.g. to use for the window

+
+ +
+ +++++ + + + + + + +

lines

Line

+
+
+
+
+

Line#

+

Specification of a single time varying quantity to plot on the Display. Note that all quantities are handled internally in LEMS in SI units, and so a scale should be used if it is to be displayed in other units.

+
+ +
+ +++++ + + + + + + + + + + +

scale

A scaling factor to DIVIDE the quantity by. Can be dimensional, so using scale=1mV means a value of -0.07V is displayed as -70. Alternatively, scale=0.001 would achieve the same thing.

Dimensions

timeScale

An optional scaling of the time axis, e.g. 1ms means display in milliseconds. Note: if present, this overrides timeScale from Display

Dimensions

+
+ +
+ ++++ + + + + + +

color

A hex string for the color to display the trace for this quantity, e.g. #aa33ff

+
+ +
+ ++++ + + + + + +

quantity

Path to the quantity to display, see see https://docs.neuroml.org/Userdocs/Paths.html.

+
+
+
+
+

OutputFile#

+

A file in which to save recorded values from the simulation.

+
+ +
+ ++++ + + + + + + + + +

path

Optional path to the directory in which to store the file

fileName

Name of the file to generate. Can include a relative path (from the LEMS Simulation file location).

+
+ +
+ +++++ + + + + + + +

outputColumn

OutputColumn

+
+
+
+
+

OutputColumn#

+

Specification of a single time varying quantity to record during the simulation. Note that all quantities are handled internally in LEMS in SI units, and so the value for the quantity in the file ( as well as time ) will be in SI units.

+
+ +
+ ++++ + + + + + +

quantity

Path to the quantity to save, see see https://docs.neuroml.org/Userdocs/Paths.html. Note that all quantities are saved in SI units.

+
+
+
+
+

EventOutputFile#

+

A file in which to save event information ( e.g. spikes from cells in a population ) in a specified format.

+
+ +
+ ++++ + + + + + + + + + + + +

path

Optional path to the directory in which to store the file

fileName

Name of the file to generate. Can include a relative path (from the LEMS Simulation file location).

format

Takes values TIME_ID or ID_TIME, depending on the preferred order of the time or event id (from EventSelection) in each row of the file

+
+ +
+ +++++ + + + + + + +

eventSelection

EventSelection

+
+
+
+
+

EventSelection#

+

A specific source of events with an associated id, which will be recorded inside the file specified in the parent EventOutputFile. The attribute select should point to a cell inside a population ( e.g. hhpop[0], see https://docs.neuroml.org/Userdocs/Paths.html ), and the eventPort specifies the port for the emitted events, which usually has id: spike. Note: the id used on this element ( and appearing in the file alongside the event time ) can be different from the id/index of the cell in the population.

+
+ +
+ ++++ + + + + + +

eventPort

The port on the cell which generates the events, usually: spike

+
+ +
+ ++++ + + + + + +

select

The cell which will be emitting the events

+
+
+
+
+

Meta#

+

Metadata to add to simulation.

+
+ +
+ ++++ + + + + + + + + + + + + + + +

for

Simulator name

method

Integration method to use

abs_tolerance

Absolute tolerance for NEURON’s cvode method

rel_tolerance

Relative tolerance for NEURON’s cvode method

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Schemas/Synapses.html b/Userdocs/Schemas/Synapses.html new file mode 100644 index 00000000..28072214 --- /dev/null +++ b/Userdocs/Schemas/Synapses.html @@ -0,0 +1,3871 @@ + + + + + + + + + + + Synapses — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Synapses#

+

A number of synaptic ComponentTypes for use in NeuroML 2 documents, e.g. expOneSynapse, expTwoSynapse, blockingPlasticSynapse. These extend the baseSynapse ComponentType. Also defined continuously transmitting synapses, e.g. gapJunction and gradedSynapse.

+
+

Original ComponentType definitions: Synapses.xml. +Schema against which NeuroML based on these should be valid: NeuroML_v2.3.xsd. +Generated on 05/12/23 from this commit. +Please file any issues or questions at the issue tracker here.

+
+
+

baseSynapse#

+

extends basePointCurrent

+

Base type for all synapses, i.e. ComponentTypes which produce a current ( dimension current ) and change Dynamics in response to an incoming event.

+

Bioportal entry for Computational Neuroscience Ontology related to baseSynapse.

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

Direction: in

+
+ +
+
<xs:complexType name="BaseSynapse">
+  <xs:complexContent>
+    <xs:extension base="Standalone">
+      <xs:attribute name="neuroLexId" type="NeuroLexId" use="optional"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseSynapse
+
+variable = BaseSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

baseVoltageDepSynapse#

+

extends baseSynapse

+

Base type for synapses with a dependence on membrane potential.

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
<xs:complexType name="BaseVoltageDepSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseVoltageDepSynapse
+
+variable = BaseVoltageDepSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

baseSynapseDL#

+

extends baseVoltageDepPointCurrentDL

+

Base type for all synapses, i.e. ComponentTypes which produce a dimensionless current and change Dynamics in response to an incoming event.

+

Bioportal entry for Computational Neuroscience Ontology related to baseSynapseDL.

+
+ +
+ +++++ + + + + + + +

I

The total (time varying) current produced by this ComponentType (from basePointCurrentDL)

Dimensionless

+
+ +
+ +++++ + + + + + + +

V

The current may vary with the dimensionless voltage exposed by the ComponentType on which this is placed (from baseVoltageDepPointCurrentDL)

Dimensionless

+
+
+
+
+

baseCurrentBasedSynapse#

+

extends baseSynapse

+

Synapse model which produces a synaptic current.

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
<xs:complexType name="BaseCurrentBasedSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseCurrentBasedSynapse
+
+variable = BaseCurrentBasedSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

alphaCurrentSynapse#

+

extends baseCurrentBasedSynapse

+

Alpha current synapse: rise time and decay time are both tau..

+
+ +
+ +++++ + + + + + + + + + + +

ibase

Baseline current increase after receiving a spike

current

tau

Time course for rise and decay

time

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

I: current

+
+

J: current

+
+
On Start

I = 0

+
+

J = 0

+
+
On Events

EVENT IN on port: in

+
+

   J = J + weight * ibase

+
+
Derived Variables

i = I (exposed as i)

+
+
Time Derivatives

d I /dt = (2.7182818284590451*J - I)/tau

+
+

d J /dt = -J/tau

+
+
+
+ +
+
<xs:complexType name="AlphaCurrentSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseCurrentBasedSynapse">
+      <xs:attribute name="tau" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="ibase" type="Nml2Quantity_current" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import AlphaCurrentSynapse
+
+variable = AlphaCurrentSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    tau: 'a Nml2Quantity_time (required)' = None,
+    ibase: 'a Nml2Quantity_current (required)' = None,
+)
+
+
+
+
+
+
+

baseConductanceBasedSynapse#

+

extends baseVoltageDepSynapse

+

Synapse model which exposes a conductance g in addition to producing a current. Not necessarily ohmic!!

+

Bioportal entry for Computational Neuroscience Ontology related to baseConductanceBasedSynapse.

+
+ +
+ +++++ + + + + + + + + + + +

erev

Reversal potential of the synapse

voltage

gbase

Baseline conductance, generally the maximum conductance following a single spike

conductance

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
<xs:complexType name="BaseConductanceBasedSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseVoltageDepSynapse">
+      <xs:attribute name="gbase" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="erev" type="Nml2Quantity_voltage" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseConductanceBasedSynapse
+
+variable = BaseConductanceBasedSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

baseConductanceBasedSynapseTwo#

+

extends baseVoltageDepSynapse

+

Synapse model suited for a sum of two expTwoSynapses which exposes a conductance g in addition to producing a current. Not necessarily ohmic!!

+

Bioportal entry for Computational Neuroscience Ontology related to baseConductanceBasedSynapseTwo.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse

voltage

gbase1

Baseline conductance 1

conductance

gbase2

Baseline conductance 2

conductance

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
<xs:complexType name="BaseConductanceBasedSynapseTwo">
+  <xs:complexContent>
+    <xs:extension base="BaseVoltageDepSynapse">
+      <xs:attribute name="gbase1" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="gbase2" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="erev" type="Nml2Quantity_voltage" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BaseConductanceBasedSynapseTwo
+
+variable = BaseConductanceBasedSynapseTwo(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase1: 'a Nml2Quantity_conductance (required)' = None,
+    gbase2: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+
+
+
+

expOneSynapse#

+

extends baseConductanceBasedSynapse

+

Ohmic synapse model whose conductance rises instantaneously by ( gbase * weight ) on receiving an event, and which decays exponentially to zero with time course tauDecay.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse (from baseConductanceBasedSynapse)

voltage

gbase

Baseline conductance, generally the maximum conductance following a single spike (from baseConductanceBasedSynapse)

conductance

tauDecay

Time course of decay

time

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse (from baseConductanceBasedSynapse)

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

g: conductance  (exposed as g)

+
+
On Start

g = 0

+
+
On Events

EVENT IN on port: in

+
+

   g = g + (weight * gbase)

+
+
Derived Variables

i = g * (erev - v) (exposed as i)

+
+
Time Derivatives

d g /dt = -g / tauDecay

+
+
+
+ +
+
<xs:complexType name="ExpOneSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseConductanceBasedSynapse">
+      <xs:attribute name="tauDecay" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ExpOneSynapse
+
+variable = ExpOneSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    tau_decay: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<expOneSynapse id="syn1" gbase="5nS" erev="0mV" tauDecay="3ms"/>
+
+
+
<expOneSynapse id="syn2" gbase="10nS" erev="0mV" tauDecay="2ms"/>
+
+
+
<expOneSynapse id="syn1" gbase="5nS" erev="0mV" tauDecay="3ms"/>
+
+
+
+
+
+
+

alphaSynapse#

+

extends baseConductanceBasedSynapse

+

Ohmic synapse model where rise time and decay time are both tau. Max conductance reached during this time ( assuming zero conductance before ) is gbase * weight..

+
+ +
+ +++++ + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse (from baseConductanceBasedSynapse)

voltage

gbase

Baseline conductance, generally the maximum conductance following a single spike (from baseConductanceBasedSynapse)

conductance

tau

Time course of rise/decay

time

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse (from baseConductanceBasedSynapse)

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

g: conductance  (exposed as g)

+
+

A: conductance

+
+
On Start

g = 0

+
+

A = 0

+
+
On Events

EVENT IN on port: in

+
+

   A = A + (gbase*weight)

+
+
Derived Variables

i = g * (erev - v) (exposed as i)

+
+
Time Derivatives

d g /dt = (2.7182818284590451 * A - g)/tau

+
+

d A /dt = -A / tau

+
+
+
+ +
+
<xs:complexType name="AlphaSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseConductanceBasedSynapse">
+      <xs:attribute name="tau" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import AlphaSynapse
+
+variable = AlphaSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    tau: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<alphaSynapse id="synalpha" gbase="0.5nS" erev="0mV" tau="2ms">
+        <notes>An alpha synapse with time for rise equal to decay.</notes>
+    </alphaSynapse>
+
+
+
+
+
+
+

expTwoSynapse#

+

extends baseConductanceBasedSynapse

+

Ohmic synapse model whose conductance waveform on receiving an event has a rise time of tauRise and a decay time of tauDecay. Max conductance reached during this time ( assuming zero conductance before ) is gbase * weight..

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse (from baseConductanceBasedSynapse)

voltage

gbase

Baseline conductance, generally the maximum conductance following a single spike (from baseConductanceBasedSynapse)

conductance

tauDecay

time

tauRise

time

+
+ +
+ +++++ + + + + + + +

peakTime

time

+

   peakTime = log(tauDecay / tauRise) * (tauRise * tauDecay)/(tauDecay - tauRise)

+ +++++ + + + + + + +

waveformFactor

Dimensionless

+

   waveformFactor = 1 / (-exp(-peakTime / tauRise) + exp(-peakTime / tauDecay))

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse (from baseConductanceBasedSynapse)

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

A: Dimensionless

+
+

B: Dimensionless

+
+
On Start

A = 0

+
+

B = 0

+
+
On Events

EVENT IN on port: in

+
+

   A = A + (weight * waveformFactor)

+
+

   B = B + (weight * waveformFactor)

+
+
Derived Variables

g = gbase * (B - A) (exposed as g)

+
+

i = g * (erev - v) (exposed as i)

+
+
Time Derivatives

d A /dt = -A / tauRise

+
+

d B /dt = -B / tauDecay

+
+
+
+ +
+
<xs:complexType name="ExpTwoSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseConductanceBasedSynapse">
+      <xs:attribute name="tauDecay" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="tauRise" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ExpTwoSynapse
+
+variable = ExpTwoSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    tau_decay: 'a Nml2Quantity_time (required)' = None,
+    tau_rise: 'a Nml2Quantity_time (required)' = None,
+    extensiontype_=None,
+)
+
+
+
+ +
+
<expTwoSynapse id="AMPA" gbase="0.5nS" erev="0mV" tauRise="1ms" tauDecay="2ms"/>
+
+
+
<expTwoSynapse id="synInput" gbase="8nS" erev="20mV" tauRise="1ms" tauDecay="5ms"/>
+
+
+
<expTwoSynapse id="synInputFast" gbase="1nS" erev="20mV" tauRise="0.2ms" tauDecay="1ms"/>
+
+
+
+
+
+
+

expThreeSynapse#

+

extends baseConductanceBasedSynapseTwo

+

Ohmic synapse similar to expTwoSynapse but consisting of two components that can differ in decay times and max conductances but share the same rise time.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse (from baseConductanceBasedSynapseTwo)

voltage

gbase1

Baseline conductance 1 (from baseConductanceBasedSynapseTwo)

conductance

gbase2

Baseline conductance 2 (from baseConductanceBasedSynapseTwo)

conductance

tauDecay1

time

tauDecay2

time

tauRise

time

+
+ +
+ +++++ + + + + + + +

peakTime1

time

+

   peakTime1 = log(tauDecay1 / tauRise) * (tauRise * tauDecay1)/(tauDecay1 - tauRise)

+ +++++ + + + + + + +

peakTime2

time

+

   peakTime2 = log(tauDecay2 / tauRise) * (tauRise * tauDecay2)/(tauDecay2 - tauRise)

+ +++++ + + + + + + +

waveformFactor1

Dimensionless

+

   waveformFactor1 = 1 / (-exp(-peakTime1 / tauRise) + exp(-peakTime1 / tauDecay1))

+ +++++ + + + + + + +

waveformFactor2

Dimensionless

+

   waveformFactor2 = 1 / (-exp(-peakTime2 / tauRise) + exp(-peakTime2 / tauDecay2))

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse (from baseConductanceBasedSynapseTwo)

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

A: Dimensionless

+
+

B: Dimensionless

+
+

C: Dimensionless

+
+
On Start

A = 0

+
+

B = 0

+
+

C = 0

+
+
On Events

EVENT IN on port: in

+
+

   A = A + (gbase1weight * waveformFactor1 + gbase2weight*waveformFactor2 )/(gbase1+gbase2)

+
+

   B = B + (weight * waveformFactor1)

+
+

   C = C + (weight * waveformFactor2)

+
+
Derived Variables

g = gbase1*(B - A) + gbase2*(C-A) (exposed as g)

+
+

i = g * (erev - v) (exposed as i)

+
+
Time Derivatives

d A /dt = -A / tauRise

+
+

d B /dt = -B / tauDecay1

+
+

d C /dt = -C / tauDecay2

+
+
+
+ +
+
<xs:complexType name="ExpThreeSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseConductanceBasedSynapseTwo">
+      <xs:attribute name="tauDecay1" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="tauDecay2" type="Nml2Quantity_time" use="required"/>
+      <xs:attribute name="tauRise" type="Nml2Quantity_time" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import ExpThreeSynapse
+
+variable = ExpThreeSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase1: 'a Nml2Quantity_conductance (required)' = None,
+    gbase2: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    tau_decay1: 'a Nml2Quantity_time (required)' = None,
+    tau_decay2: 'a Nml2Quantity_time (required)' = None,
+    tau_rise: 'a Nml2Quantity_time (required)' = None,
+)
+
+
+
+ +
+
<expThreeSynapse id="synInputFastTwo" gbase1="1.5nS" tauRise="0.1ms" tauDecay1="0.7ms" gbase2="0.5nS" tauDecay2="2.5ms" erev="0mV"/>
+
+
+
<expThreeSynapse id="AMPA" gbase1="1.5nS" tauRise="0.1ms" tauDecay1="0.7ms" gbase2="0.5nS" tauDecay2="2.5ms" erev="0mV">
+        <notes>A synapse consisting of one rise and two decay time courses.</notes>
+    </expThreeSynapse>
+
+
+
+
+
+
+

baseBlockMechanism#

+

Base of any ComponentType which produces a varying scaling ( or blockage ) of synaptic strength of magnitude scaling.

+
+ +
+ +++++ + + + + + + +

blockFactor

Dimensionless

+
+
+
+
+

voltageConcDepBlockMechanism#

+

extends baseBlockMechanism

+

Synaptic blocking mechanism which varys with membrane potential across the synapse, e.g. in NMDA receptor mediated synapses.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

blockConcentration

concentration

scalingConc

concentration

scalingVolt

voltage

+
+ +
+ ++++ + + + + + +

species

+
+ +
+ +++++ + + + + + + +

blockFactor

(from baseBlockMechanism)

Dimensionless

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+ +
+
+
Derived Variables

blockFactor = 1/(1 + (blockConcentration / scalingConc)* exp(-1 * (v / scalingVolt))) (exposed as blockFactor)

+
+
+
+
+
+
+

basePlasticityMechanism#

+

Base plasticity mechanism.

+
+ +
+ +++++ + + + + + + +

plasticityFactor

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

This is where the plasticity mechanism receives spike events from the parent synapse.

Direction: in

+
+
+
+
+

tsodyksMarkramDepMechanism#

+

extends basePlasticityMechanism

+

Depression-only Tsodyks-Markram model, as in Tsodyks and Markram 1997.

+
+ +
+ +++++ + + + + + + + + + + +

initReleaseProb

Dimensionless

tauRec

time

+
+ +
+ +++++ + + + + + + +

plasticityFactor

(from basePlasticityMechanism)

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

This is where the plasticity mechanism receives spike events from the parent synapse. (from basePlasticityMechanism)

Direction: in

+
+ +
+
+
Structure

WITH parent AS a

+
+

WITH this AS b

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

R: Dimensionless

+
+
On Start

R = 1

+
+
On Events

EVENT IN on port: in

+
+

   R = R * (1 - U)

+
+
Derived Variables

U = initReleaseProb

+
+

plasticityFactor = R * U (exposed as plasticityFactor)

+
+
Time Derivatives

d R /dt = (1 - R) / tauRec

+
+
+
+
+
+
+

tsodyksMarkramDepFacMechanism#

+

extends basePlasticityMechanism

+

Full Tsodyks-Markram STP model with both depression and facilitation, as in Tsodyks, Pawelzik and Markram 1998.

+
+ +
+ +++++ + + + + + + + + + + + + + + +

initReleaseProb

Dimensionless

tauFac

time

tauRec

time

+
+ +
+ +++++ + + + + + + +

plasticityFactor

(from basePlasticityMechanism)

Dimensionless

+
+ +
+ +++++ + + + + + + +

in

This is where the plasticity mechanism receives spike events from the parent synapse. (from basePlasticityMechanism)

Direction: in

+
+ +
+
+
Structure

WITH parent AS a

+
+

WITH this AS b

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

R: Dimensionless

+
+

U: Dimensionless

+
+
On Start

R = 1

+
+

U = initReleaseProb

+
+
On Events

EVENT IN on port: in

+
+

   R = R * (1 - U)

+
+

   U = U + initReleaseProb * (1 - U)

+
+
Derived Variables

plasticityFactor = R * U (exposed as plasticityFactor)

+
+
Time Derivatives

d R /dt = (1 - R) / tauRec

+
+

d U /dt = (initReleaseProb - U) / tauFac

+
+
+
+
+
+
+

blockingPlasticSynapse#

+

extends expTwoSynapse

+

Biexponential synapse that allows for optional block and plasticity mechanisms, which can be expressed as child elements.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse (from baseConductanceBasedSynapse)

voltage

gbase

Baseline conductance, generally the maximum conductance following a single spike (from baseConductanceBasedSynapse)

conductance

tauDecay

(from expTwoSynapse)

time

tauRise

(from expTwoSynapse)

time

+
+ +
+ +++++ + + + + + + +

peakTime

(from expTwoSynapse)

time

+

   peakTime = log(tauDecay / tauRise) * (tauRise * tauDecay)/(tauDecay - tauRise)

+ +++++ + + + + + + +

waveformFactor

(from expTwoSynapse)

Dimensionless

+

   waveformFactor = 1 / (-exp(-peakTime / tauRise) + exp(-peakTime / tauDecay))

+
+ +
+ +++++ + + + + + + + + + + +

plasticityMechanisms

basePlasticityMechanism

blockMechanisms

baseBlockMechanism

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + +

g

Time varying conductance through the synapse (from baseConductanceBasedSynapse)

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + + + + + +

in

(from baseSynapse)

Direction: in

relay

Used to relay incoming spikes to child plasticity mechanism

Direction: out

+
+ +
+
+
State Variables

A: Dimensionless

+
+

B: Dimensionless

+
+
On Start

A = 0

+
+

B = 0

+
+
On Events

EVENT IN on port: in

+
+

   A = A + (weight * plasticityFactor * waveformFactor)

+
+

   B = B + (weight * plasticityFactor * waveformFactor)

+
+

   EVENT OUT on port: relay

+
+
Derived Variables

plasticityFactor = plasticityMechanisms[*]->plasticityFactor(reduce method: multiply)

+
+

blockFactor = blockMechanisms[*]->blockFactor(reduce method: multiply)

+
+

g = blockFactor * gbase * (B - A) (exposed as g)

+
+

i = g * (erev - v) (exposed as i)

+
+
Time Derivatives

d A /dt = -A / tauRise

+
+

d B /dt = -B / tauDecay

+
+
+
+ +
+
<xs:complexType name="BlockingPlasticSynapse">
+  <xs:complexContent>
+    <xs:extension base="ExpTwoSynapse">
+      <xs:sequence>
+        <xs:element name="plasticityMechanism" type="PlasticityMechanism" minOccurs="0"/>
+        <xs:element name="blockMechanism" type="BlockMechanism" minOccurs="0"/>
+      </xs:sequence>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import BlockingPlasticSynapse
+
+variable = BlockingPlasticSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    gbase: 'a Nml2Quantity_conductance (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+    tau_decay: 'a Nml2Quantity_time (required)' = None,
+    tau_rise: 'a Nml2Quantity_time (required)' = None,
+    plasticity_mechanism: 'a PlasticityMechanism (optional)' = None,
+    block_mechanism: 'a BlockMechanism (optional)' = None,
+)
+
+
+
+ +
+
<blockingPlasticSynapse id="NMDA" gbase=".8nS" tauRise="1e-3s" tauDecay="13.3333e-3s" erev="0V">
+        <blockMechanism type="voltageConcDepBlockMechanism" species="mg" blockConcentration="1.2mM" scalingConc="1.9205441817997078mM" scalingVolt="0.016129032258064516V"/>
+    </blockingPlasticSynapse>
+
+
+
<blockingPlasticSynapse id="blockStpSynDep" gbase="1nS" erev="0mV" tauRise="0.1ms" tauDecay="2ms">
+        <notes>A biexponential blocking synapse, with STD.</notes>
+        <plasticityMechanism type="tsodyksMarkramDepMechanism" initReleaseProb="0.5" tauRec="120 ms"/>
+        <blockMechanism type="voltageConcDepBlockMechanism" species="mg" blockConcentration="1.2 mM" scalingConc="1.920544 mM" scalingVolt="16.129 mV"/>
+    </blockingPlasticSynapse>
+
+
+
<blockingPlasticSynapse id="blockStpSynDepFac" gbase="1nS" erev="0mV" tauRise="0.1ms" tauDecay="2ms">
+        <notes>A biexponential blocking synapse with short term
+            depression and facilitation.</notes>
+        <plasticityMechanism type="tsodyksMarkramDepFacMechanism" initReleaseProb="0.5" tauRec="120 ms" tauFac="10 ms"/>
+        <blockMechanism type="voltageConcDepBlockMechanism" species="mg" blockConcentration="1.2 mM" scalingConc="1.920544 mM" scalingVolt="16.129 mV"/>
+    </blockingPlasticSynapse>
+
+
+
+
+
+
+

doubleSynapse#

+

extends baseVoltageDepSynapse

+

Synapse consisting of two independent synaptic mechanisms ( e.g. AMPA-R and NMDA-R ), which can be easily colocated in connections.

+
+ +
+ ++++ + + + + + + + + +

synapse1Path

synapse2Path

+
+ +
+ +++++ + + + + + + + + + + +

synapse1

baseSynapse

synapse2

baseSynapse

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + + + + + +

in

(from baseSynapse)

Direction: in

relay

Used to relay incoming spikes to child mechanisms

Direction: out

+
+ +
+
+
Structure

WITH this AS a

+
+

WITH synapse1Path AS b

+
+

WITH synapse2Path AS c

+
+

CHILD INSTANCE: synapse1

+
+

CHILD INSTANCE: synapse2

+
+

EVENT CONNECTION from a TO c

+
+

EVENT CONNECTION from a TO b

+
+
State Variables

weightFactor: Dimensionless

+
+
On Events

EVENT IN on port: in

+
+

   weightFactor = weight

+
+

   EVENT OUT on port: relay

+
+
Derived Variables

i1 = synapse1->i

+
+

i2 = synapse2->i

+
+

i = weightFactor * (i1 + i2) (exposed as i)

+
+
+
+ +
+
<xs:complexType name="DoubleSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseVoltageDepSynapse">
+      <xs:attribute name="synapse1" type="NmlId" use="required"/>
+      <xs:attribute name="synapse2" type="NmlId" use="required"/>
+      <xs:attribute name="synapse1Path" type="xs:string" use="required"/>
+      <xs:attribute name="synapse2Path" type="xs:string" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import DoubleSynapse
+
+variable = DoubleSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    synapse1: 'a NmlId (required)' = None,
+    synapse2: 'a NmlId (required)' = None,
+    synapse1_path: 'a string (required)' = None,
+    synapse2_path: 'a string (required)' = None,
+)
+
+
+
+ +
+
<doubleSynapse id="AMPA_NMDA" synapse1="AMPA" synapse1Path="./AMPA" synapse2="NMDA" synapse2Path="./NMDA">
+        <notes>A single "synapse" which contains both AMPA and NMDA. It is planned that the need for extra synapse1Path/synapse2Path attributes can be removed in later versions.</notes>
+    </doubleSynapse>
+
+
+
+
+
+
+

stdpSynapse#

+

extends expTwoSynapse

+

Spike timing dependent plasticity mechanism, NOTE: EXAMPLE NOT YET WORKING!!!

+

Bioportal entry for Computational Neuroscience Ontology related to stdpSynapse.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + +

erev

Reversal potential of the synapse (from baseConductanceBasedSynapse)

voltage

gbase

Baseline conductance, generally the maximum conductance following a single spike (from baseConductanceBasedSynapse)

conductance

tauDecay

(from expTwoSynapse)

time

tauRise

(from expTwoSynapse)

time

+
+ +
+ +++++ + + + + + + + + + + +

tsinceRate = 1

Dimensionless

longTime = 1000s

time

+
+ +
+ +++++ + + + + + + +

peakTime

(from expTwoSynapse)

time

+

   peakTime = log(tauDecay / tauRise) * (tauRise * tauDecay)/(tauDecay - tauRise)

+ +++++ + + + + + + +

waveformFactor

(from expTwoSynapse)

Dimensionless

+

   waveformFactor = 1 / (-exp(-peakTime / tauRise) + exp(-peakTime / tauDecay))

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

M

Dimensionless

P

Dimensionless

g

Time varying conductance through the synapse (from baseConductanceBasedSynapse)

conductance

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

tsince

time

+
+ +
+ +++++ + + + + + + +

v

The current may vary with the voltage exposed by the ComponentType on which this is placed (from baseVoltageDepSynapse)

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

A: Dimensionless

+
+

B: Dimensionless

+
+

M: Dimensionless  (exposed as M)

+
+

P: Dimensionless  (exposed as P)

+
+

tsince: time  (exposed as tsince)

+
+
On Start

A = 0

+
+

B = 0

+
+

M = 1

+
+

P = 1

+
+

tsince = longTime

+
+
On Events

EVENT IN on port: in

+
+

   A = A + waveformFactor

+
+

   B = B + waveformFactor

+
+

   tsince = 0

+
+
Derived Variables

g = gbase * (B - A) (exposed as g)

+
+

i = g * (erev - v) (exposed as i)

+
+
Time Derivatives

d A /dt = -A / tauRise

+
+

d B /dt = -B / tauDecay

+
+

d tsince /dt = tsinceRate

+
+
+
+
+
+
+

gapJunction#

+

extends baseSynapse

+

Gap junction/single electrical connection.

+
+ +
+ +++++ + + + + + + +

conductance

conductance

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
Derived Variables

vpeer = peer->v

+
+

i = weight * conductance * (vpeer - v) (exposed as i)

+
+
+
+ +
+
<xs:complexType name="GapJunction">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+      <xs:attribute name="conductance" type="Nml2Quantity_conductance" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import GapJunction
+
+variable = GapJunction(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (required)' = None,
+)
+
+
+
+ +
+
<gapJunction id="gj1" conductance="10pS"/>
+
+
+
<gapJunction id="gj1" conductance="10pS"/>
+
+
+
+
+
+
+

baseGradedSynapse#

+

extends baseSynapse

+

Base type for graded synapses.

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+
+
+
+

silentSynapse#

+

extends baseGradedSynapse

+

Dummy synapse which emits no current. Used as presynaptic endpoint for analog synaptic connection.

+
+ +
+ +++++ + + + + + + +

AMP = 1A

current

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
Derived Variables

vpeer = peer->v

+
+

i = 0 * AMP (exposed as i)

+
+
+
+ +
+
<xs:complexType name="SilentSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+
+            </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import SilentSynapse
+
+variable = SilentSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+)
+
+
+
+ +
+
<silentSynapse id="silent1"/>
+
+
+
<silentSynapse id="silent2"/>
+
+
+
<silentSynapse id="silent1"/>
+
+
+
+
+
+
+

linearGradedSynapse#

+

extends baseGradedSynapse

+

Behaves just like a one way gap junction.

+
+ +
+ +++++ + + + + + + +

conductance

conductance

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
Derived Variables

vpeer = peer->v

+
+

i = weight * conductance * (vpeer - v) (exposed as i)

+
+
+
+ +
+
<xs:complexType name="LinearGradedSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+      <xs:attribute name="conductance" type="Nml2Quantity_conductance" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import LinearGradedSynapse
+
+variable = LinearGradedSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (required)' = None,
+)
+
+
+
+ +
+
<linearGradedSynapse id="gs1" conductance="5pS"/>
+
+
+
+
+
+
+

gradedSynapse#

+

extends baseGradedSynapse

+

Graded/analog synapse. Based on synapse in Methods of http://www.nature.com/neuro/journal/v7/n12/abs/nn1352.html.

+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + +

Vth

The half-activation voltage of the synapse

voltage

conductance

conductance

delta

Slope of the activation curve

voltage

erev

The reversal potential of the synapse

voltage

k

Rate constant for transmitter-receptor dissociation rate

per_time

+
+ +
+ +++++ + + + + + + +

weight (default: 1)

Dimensionless

+
+ +
+ +++++ + + + + + + + + + + + + + + +

i

The total (usually time varying) current produced by this ComponentType (from basePointCurrent)

current

inf

Dimensionless

tau

time

+
+ +
+ +++++ + + + + + + +

v

voltage

+
+ +
+ +++++ + + + + + + +

in

(from baseSynapse)

Direction: in

+
+ +
+
+
State Variables

s: Dimensionless

+
+
On Conditions

IF (1-inf) < 1e-4 THEN

+
+

   s = inf

+
+
Derived Variables

vpeer = peer->v

+
+

inf = 1/(1 + exp((Vth - vpeer)/delta)) (exposed as inf)

+
+

tau = (1-inf)/k (exposed as tau)

+
+

i = weight * conductance * s * (erev-v) (exposed as i)

+
+
Conditional Derived Variables

IF (1-inf) > 1e-4 THEN

+
+

s_rate = (inf - s)/tau

+
+

OTHERWISE

+
+

s_rate = 0

+
+
Time Derivatives

d s /dt = s_rate

+
+
+
+ +
+
<xs:complexType name="GradedSynapse">
+  <xs:complexContent>
+    <xs:extension base="BaseSynapse">
+      <xs:attribute name="conductance" type="Nml2Quantity_conductance" use="required"/>
+      <xs:attribute name="delta" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="Vth" type="Nml2Quantity_voltage" use="required"/>
+      <xs:attribute name="k" type="Nml2Quantity_pertime" use="required"/>
+      <xs:attribute name="erev" type="Nml2Quantity_voltage" use="required"/>
+    </xs:extension>
+  </xs:complexContent>
+</xs:complexType>
+
+
+
+ +
+

Go to the libNeuroML documentation

+
from neuroml import GradedSynapse
+
+variable = GradedSynapse(
+    id: 'a NmlId (required)' = None,
+    metaid: 'a MetaId (optional)' = None,
+    notes: 'a string (optional)' = None,
+    properties: 'list of Property(s) (optional)' = None,
+    annotation: 'a Annotation (optional)' = None,
+    neuro_lex_id: 'a NeuroLexId (optional)' = None,
+    conductance: 'a Nml2Quantity_conductance (required)' = None,
+    delta: 'a Nml2Quantity_voltage (required)' = None,
+    Vth: 'a Nml2Quantity_voltage (required)' = None,
+    k: 'a Nml2Quantity_pertime (required)' = None,
+    erev: 'a Nml2Quantity_voltage (required)' = None,
+)
+
+
+
+ +
+
<gradedSynapse id="gs2" conductance="5pS" delta="5mV" Vth="-55mV" k="0.025per_ms" erev="0mV"/>
+
+
+
<gradedSynapse id="gs1" conductance="0.1nS" delta="5mV" Vth="-35mV" k="0.025per_ms" erev="0mV"/>
+
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/SimulatingNeuroMLModels.html b/Userdocs/SimulatingNeuroMLModels.html new file mode 100644 index 00000000..b3ecdb29 --- /dev/null +++ b/Userdocs/SimulatingNeuroMLModels.html @@ -0,0 +1,825 @@ + + + + + + + + + + + Simulating NeuroML Models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Simulating NeuroML Models

+ +
+ +
+
+ + + + +
+ +
+

Simulating NeuroML Models#

+
+

Validate NeuroML 2 files before using them.

+

It is good practice to validate NeuroML 2 files to check them for correctness before simulating them.

+
+
+

Using Open Source Brain#

+

Models that have already been converted to NeuroML and added to the Open Source Brain platform can be simulated through your browser.

+
+Open Source Brain +
+

Fig. 43 Examples of NeuroML 2 models visualised on Open Source Brain. A) Hodgkin Huxley model interactive tutorial. B) Integrate and fire network model of cortical column (Potjans and Diesmann 2014), showing network connectivity. C) Cortical model with multicompartmental cells (Traub et al. 2005), showing network properties and simulated membrane potential activity. D) Model of C. elegans nervous system from OpenWorm project. All visualisation/analysis/simulation enabled due to models being in standardised NeuroML format.#

+
+
+

Most of the OSB example projects feature prebuilt NeuroML models which can be simulated in this way.

+

A discussion on the steps required for sharing your own models on OSB, with a view to simulating them on the platform, can be found here.

+
+
+

Using jNeuroML/pyNeuroML#

+

jLEMS is the reference implementation of the LEMS language in Java, and can be used to simulate single compartment models written in NeuroML/LEMS. +It is included in both jNeuroML and pyNeuroML.

+
+jNeuroML and pyNeuroML +
+

Fig. 44 Relationship between jLEMS, jNeuroML and pyNeuroML.#

+
+
+

jNeuroML and pyNeuroML can be used at the command line as follows, when a LEMS Simulation file has been created to describe what to simulate/plot/save:

+
# Simulate the model using jNeuroML
+jnml <LEMS simulation file>
+
+# Simulate the model using pyNeuroML
+pynml <LEMS simulation file>
+
+
+

You can also run LEMS simulations using jNeuroML straight from a Python script using the pyNeuroML API:

+
from pyneuroml.pynml import run_lems_with_jneuroml
+
+...
+
+run_lems_with_jneuroml(lems_file_name)
+
+
+
+
+

Using NEURON#

+

For more complex models that can not be simulated using jLEMS (e.g. incorporating multicompartmental cells), we can use the NEURON simulator, also using jNeuroML or pyNeuroML, pointing at a LEMS Simulation file describing what to simulate, and using the -neuron option:

+
# Simulate the model using NEURON with python/hoc/mod files generated by jNeuroML
+jnml <LEMS simulation file> -neuron -run
+
+# Simulate the model using NEURON with python/hoc/mod files generated by pyNeuroML
+pynml <LEMS simulation file> -neuron -run
+
+
+

You can also run LEMS simulations using the NEURON simulator using the pyNeuroML API:

+
from pyneuroml.pynml import run_lems_with_jneuroml_neuron
+
+...
+
+run_lems_with_jneuroml_neuron(lems_file_name)
+
+
+

There is a dedicated page on NEURON/NeuroML interactions here.

+
+
+

Using NetPyNE#

+

You can also generate and run NetPyNE code from NeuroML. +To generate and run NetPyNE code, use jNeuroML or pyNeuroML:

+
# Simulate the model using NetPyNE with python/hoc/mod files generated by jNeuroML
+jnml <LEMS simulation file> -netpyne -run
+
+# Simulate the model using NetPyNE with python/hoc/mod files generated by pyNeuroML
+pynml <LEMS simulation file> -netpyne -run
+
+
+

The main generated Python file name will end in _netpyne.py.

+

You can also run LEMS simulations using the NetPyNE simulator using the pyNeuroML API:

+
from pyneuroml.pynml import run_lems_with_jneuroml_netpyne
+
+...
+
+run_lems_with_jneuroml_netpyne(lems_file_name)
+
+
+

There is a dedicated page on NetPyNE/NeuroML interactions here.

+
+
+

Using Brian2#

+

You can export single component NeuroML models to Python scripts for running them using the Brian2 simulator:

+
# Using jnml
+jnml <LEMS simulation file> -brian2
+
+# Using pynml
+pynml <LEMS simulation file> -brian2
+
+
+

You can also run LEMS simulations using the Brian2 simulator using the pyNeuroML API:

+
from pyneuroml.pynml import run_lems_with_jneuroml_brian2
+
+...
+
+run_lems_with_jneuroml_brian2(lems_file_name)
+
+
+

There is a dedicated page on Brian/NeuroML interactions here.

+
+
+

Using MOOSE#

+

You can export NeuroML models to the MOOSE simulator format using jNeuroML or pyNeuroML, pointing at a LEMS Simulation file describing what to simulate, and using the -moose option:

+
# Using jnml
+jnml <LEMS simulation file> -moose
+
+# Using pynml
+pynml <LEMS simulation file> -moose
+
+
+

There is a dedicated page on MOOSE/NeuroML interactions here.

+
+
+

Using EDEN#

+

The EDEN simulator can load and simulate NeuroML v2 models.

+

There is a dedicated page on EDEN/NeuroML interactions here.

+
+
+

Using Arbor#

+

You can import NeuroML models to the Arbor simulator.

+

There is a dedicated page on Arbor/NeuroML interactions here.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/SingleCompartmentHHExample.html b/Userdocs/SingleCompartmentHHExample.html new file mode 100644 index 00000000..4703a2aa --- /dev/null +++ b/Userdocs/SingleCompartmentHHExample.html @@ -0,0 +1,1873 @@ + + + + + + + + + + + Simulating a single compartment Hodgkin-Huxley neuron — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Simulating a single compartment Hodgkin-Huxley neuron#

+

In this section we will model and simulate a Hodgkin-Huxley (HH) neuron ([HH52]). +A Hodgkin-Huxley neuron includes Sodium (Na), Potassium (K), and leak ion channels. +For further information on this neuron model, please see here.

+
+Membrane potential for neuron recorded from the simulation +
+

Fig. 13 Membrane potential of the simulated Hodgkin-Huxley neuron.#

+
+
+

This plot, saved as HH_single_compartment_example_sim-v.png is generated using the following Python NeuroML script:

+
#!/usr/bin/env python3
+"""
+Create a network with a single HH cell, and simulate it.
+
+File: hh-single-compartment.py
+
+Copyright 2023 NeuroML contributors
+Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
+"""
+
+import math
+import neuroml
+from neuroml import NeuroMLDocument
+from neuroml import Network, Population
+from neuroml import PulseGenerator, ExplicitInput
+import numpy as np
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+from neuroml.utils import component_factory
+
+
+def main():
+    """Main function
+
+    Include the NeuroML model into a LEMS simulation file, run it, plot some
+    data.
+    """
+    # Simulation bits
+    sim_id = "HH_single_compartment_example_sim"
+    simulation = LEMSSimulation(
+        sim_id=sim_id, duration=300, dt=0.01, simulation_seed=123
+    )
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_hh_cell_network")
+
+    # Recording information from the simulation
+    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+    simulation.add_column_to_output_file(
+        "output0", column_id="pop0[0]/v", quantity="pop0[0]/v"
+    )
+    simulation.add_column_to_output_file(
+        "output0", column_id="pop0[0]/iChannels", quantity="pop0[0]/iChannels"
+    )
+    simulation.add_column_to_output_file(
+        "output0",
+        column_id="pop0[0]/na/iDensity",
+        quantity="pop0[0]/biophys/membraneProperties/na_channels/iDensity/",
+    )
+    simulation.add_column_to_output_file(
+        "output0",
+        column_id="pop0[0]/k/iDensity",
+        quantity="pop0[0]/biophys/membraneProperties/k_channels/iDensity/",
+    )
+
+    # Save LEMS simulation to file
+    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the default jNeuroML simulator
+    pynml.run_lems_with_jneuroml(sim_file, max_memory="2G", nogui=True, plot=False)
+    # Plot the data
+    plot_data(sim_id)
+
+
+def plot_data(sim_id):
+    """Plot the sim data.
+
+    Load the data from the file and plot the graph for the membrane potential
+    using the pynml generate_plot utility function.
+
+    :sim_id: ID of simulaton
+
+    """
+    data_array = np.loadtxt(sim_id + ".dat")
+    pynml.generate_plot(
+        [data_array[:, 0]],
+        [data_array[:, 1]],
+        "Membrane potential",
+        show_plot_already=False,
+        save_figure_to=sim_id + "-v.png",
+        xaxis="time (s)",
+        yaxis="membrane potential (V)",
+    )
+    pynml.generate_plot(
+        [data_array[:, 0]],
+        [data_array[:, 2]],
+        "channel current",
+        show_plot_already=False,
+        save_figure_to=sim_id + "-i.png",
+        xaxis="time (s)",
+        yaxis="channel current (A)",
+    )
+    pynml.generate_plot(
+        [data_array[:, 0], data_array[:, 0]],
+        [data_array[:, 3], data_array[:, 4]],
+        "current density",
+        labels=["Na", "K"],
+        show_plot_already=False,
+        save_figure_to=sim_id + "-iden.png",
+        xaxis="time (s)",
+        yaxis="current density (A_per_m2)",
+    )
+
+
+def create_na_channel():
+    """Create the Na channel.
+
+    This will create the Na channel and save it to a file.
+    It will also validate this file.
+
+    returns: name of the created file
+    """
+    na_channel = component_factory(
+        "IonChannelHH",
+        id="na_channel",
+        notes="Sodium channel for HH cell",
+        conductance="10pS",
+        species="na",
+        validate=False,
+    )
+    gate_m = component_factory(
+        "GateHHRates",
+        id="m",
+        instances="3",
+        notes="m gate for na channel",
+        validate=False,
+    )
+    m_forward_rate = component_factory(
+        "HHRate", type="HHExpLinearRate", rate="1per_ms", midpoint="-40mV", scale="10mV"
+    )
+    m_reverse_rate = component_factory(
+        "HHRate", type="HHExpRate", rate="4per_ms", midpoint="-65mV", scale="-18mV"
+    )
+
+    gate_m.add(m_forward_rate, hint="forward_rate", validate=False)
+    gate_m.add(m_reverse_rate, hint="reverse_rate")
+    na_channel.add(gate_m)
+
+    gate_h = component_factory(
+        "GateHHRates",
+        id="h",
+        instances="1",
+        notes="h gate for na channel",
+        validate=False,
+    )
+    h_forward_rate = component_factory(
+        "HHRate", type="HHExpRate", rate="0.07per_ms", midpoint="-65mV", scale="-20mV"
+    )
+    h_reverse_rate = component_factory(
+        "HHRate", type="HHSigmoidRate", rate="1per_ms", midpoint="-35mV", scale="10mV"
+    )
+    gate_h.add(h_forward_rate, hint="forward_rate", validate=False)
+    gate_h.add(h_reverse_rate, hint="reverse_rate")
+    na_channel.add(gate_h)
+
+    na_channel_doc = component_factory(
+        "NeuroMLDocument", id="na_channel", notes="Na channel for HH neuron"
+    )
+    na_channel_fn = "HH_example_na_channel.nml"
+    na_channel_doc.add(na_channel)
+    na_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=na_channel_doc, nml2_file_name=na_channel_fn, validate=True
+    )
+
+    return na_channel_fn
+
+
+def create_k_channel():
+    """Create the K channel
+
+    This will create the K channel and save it to a file.
+    It will also validate this file.
+
+    :returns: name of the K channel file
+    """
+    k_channel = component_factory(
+        "IonChannelHH",
+        id="k_channel",
+        notes="Potassium channel for HH cell",
+        conductance="10pS",
+        species="k",
+        validate=False,
+    )
+    gate_n = component_factory(
+        "GateHHRates",
+        id="n",
+        instances="4",
+        notes="n gate for k channel",
+        validate=False,
+    )
+    n_forward_rate = component_factory(
+        "HHRate",
+        type="HHExpLinearRate",
+        rate="0.1per_ms",
+        midpoint="-55mV",
+        scale="10mV",
+    )
+    n_reverse_rate = component_factory(
+        "HHRate", type="HHExpRate", rate="0.125per_ms", midpoint="-65mV", scale="-80mV"
+    )
+    gate_n.add(n_forward_rate, hint="forward_rate", validate=False)
+    gate_n.add(n_reverse_rate, hint="reverse_rate")
+    k_channel.add(gate_n)
+
+    k_channel_doc = component_factory(
+        "NeuroMLDocument", id="k_channel", notes="k channel for HH neuron"
+    )
+    k_channel_fn = "HH_example_k_channel.nml"
+    k_channel_doc.add(k_channel)
+    k_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=k_channel_doc, nml2_file_name=k_channel_fn, validate=True
+    )
+
+    return k_channel_fn
+
+
+def create_leak_channel():
+    """Create a leak channel
+
+    This will create the leak channel and save it to a file.
+    It will also validate this file.
+
+    :returns: name of leak channel nml file
+    """
+    leak_channel = component_factory(
+        "IonChannelHH", id="leak_channel", conductance="10pS", notes="Leak conductance"
+    )
+    leak_channel_doc = component_factory(
+        "NeuroMLDocument", id="leak_channel", notes="leak channel for HH neuron"
+    )
+    leak_channel_fn = "HH_example_leak_channel.nml"
+    leak_channel_doc.add(leak_channel)
+    leak_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=leak_channel_doc, nml2_file_name=leak_channel_fn, validate=True
+    )
+
+    return leak_channel_fn
+
+
+def create_cell():
+    """Create the cell.
+
+    :returns: name of the cell nml file
+    """
+    # Create the nml file and add the ion channels
+    hh_cell_doc = NeuroMLDocument(id="cell", notes="HH cell")
+    hh_cell_fn = "HH_example_cell.nml"
+
+    # Define a cell
+    hh_cell = hh_cell_doc.add(
+        "Cell", id="hh_cell", notes="A single compartment HH cell"
+    )  # type: neuroml.Cell
+    hh_cell.info(show_contents=True)
+
+    # Channel density for Na channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="na_channels",
+        cond_density="120.0 mS_per_cm2",
+        erev="50.0 mV",
+        ion="na",
+        ion_channel="na_channel",
+        ion_chan_def_file=create_na_channel(),
+    )
+
+    # Channel density for k channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="k_channels",
+        cond_density="360 S_per_m2",
+        erev="-77mV",
+        ion="k",
+        ion_channel="k_channel",
+        ion_chan_def_file=create_k_channel(),
+    )
+    # Leak channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="leak_channels",
+        cond_density="3.0 S_per_m2",
+        erev="-54.3mV",
+        ion="non_specific",
+        ion_channel="leak_channel",
+        ion_chan_def_file=create_leak_channel(),
+    )
+
+    # Other membrane properties
+    hh_cell.add_membrane_property("SpikeThresh", value="-20mV")
+    hh_cell.set_specific_capacitance("1.0 uF_per_cm2")
+    hh_cell.set_init_memb_potential("-65mV")
+
+    hh_cell.set_resistivity("0.03 kohm_cm")
+
+    # We want a diameter such that area is 1000 micro meter^2
+    # surface area of a sphere is 4pi r^2 = 4pi diam^2
+    diam = math.sqrt(1000 / math.pi)
+    hh_cell.add_segment(
+        prox=[0, 0, 0, diam],
+        dist=[0, 0, 0, diam],
+        name="soma",
+        parent=None,
+        fraction_along=1.0,
+        group="soma_0",
+    )
+
+    hh_cell_doc.validate(recursive=True)
+    pynml.write_neuroml2_file(
+        nml2_doc=hh_cell_doc, nml2_file_name=hh_cell_fn, validate=True
+    )
+    return hh_cell_fn
+
+
+def create_network():
+    """Create the network
+
+    :returns: name of network nml file
+    """
+    net_doc = component_factory(
+        "NeuroMLDocument", id="network", notes="HH cell network"
+    )
+    net_doc_fn = "HH_example_net.nml"
+    net_doc.add("IncludeType", href=create_cell())
+    net = net_doc.add("Network", id="single_hh_cell_network", validate=False)
+
+    # Create a population: convenient to create many cells of the same type
+    pop = net.add(
+        "Population",
+        id="pop0",
+        notes="A population for our cell",
+        component="hh_cell",
+        size=1,
+    )
+
+    # Input
+    pulsegen = net_doc.add(
+        "PulseGenerator",
+        id="pg",
+        notes="Simple pulse generator",
+        delay="100ms",
+        duration="100ms",
+        amplitude="0.08nA",
+    )
+
+    exp_input = net.add("ExplicitInput", target="pop0[0]", input="pg")
+
+    net_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True
+    )
+    return net_doc_fn
+
+
+if __name__ == "__main__":
+    main()
+
+
+
+

Declaring the model in NeuroML#

+

Similar to previous examples, we will first declare the model, visualise it, and then simulate it. +The HH neuron model is more complex than the Izhikevich neuron model we have seen so far. +For example, it includes voltage-gated ion channels. +We will first implement these ion channels in NeuroML, then add them to a cell. +We will then create a network of one cell which will will stimulate with external input to record the membrane potential.

+

As you can also see in the script, since this is a slightly more complex model, we have modularised our code into different functions that carry out different tasks. +Let us now step through the script in a bottom-up fashion. +We start with the ion channels and build the network simulation.

+
+

Declaring ion channels#

+
+

Note: you might not need to define your ion channels in Python every time…

+

In this example, all parts of the model, including the ion channels, are defined from scratch in Python and then NeuroML files in XML are generated and saved. For many modelling projects however, ion channel XML files will be reused from other models, and can just be included in the cells that use them with: <include href="my_channel.nml"/>. See here for tips on where to find ion channel models in NeuroML.

+
+

Let us look at the definition of the Sodium (Na) channel in NeuroML:

+
def create_na_channel():
+    """Create the Na channel.
+
+    This will create the Na channel and save it to a file.
+    It will also validate this file.
+
+    returns: name of the created file
+    """
+    na_channel = component_factory(
+        "IonChannelHH",
+        id="na_channel",
+        notes="Sodium channel for HH cell",
+        conductance="10pS",
+        species="na",
+        validate=False,
+    )
+    gate_m = component_factory(
+        "GateHHRates",
+        id="m",
+        instances="3",
+        notes="m gate for na channel",
+        validate=False,
+    )
+    m_forward_rate = component_factory(
+        "HHRate", type="HHExpLinearRate", rate="1per_ms", midpoint="-40mV", scale="10mV"
+    )
+    m_reverse_rate = component_factory(
+        "HHRate", type="HHExpRate", rate="4per_ms", midpoint="-65mV", scale="-18mV"
+    )
+
+    gate_m.add(m_forward_rate, hint="forward_rate", validate=False)
+    gate_m.add(m_reverse_rate, hint="reverse_rate")
+    na_channel.add(gate_m)
+
+    gate_h = component_factory(
+        "GateHHRates",
+        id="h",
+        instances="1",
+        notes="h gate for na channel",
+        validate=False,
+    )
+    h_forward_rate = component_factory(
+        "HHRate", type="HHExpRate", rate="0.07per_ms", midpoint="-65mV", scale="-20mV"
+    )
+    h_reverse_rate = component_factory(
+        "HHRate", type="HHSigmoidRate", rate="1per_ms", midpoint="-35mV", scale="10mV"
+    )
+    gate_h.add(h_forward_rate, hint="forward_rate", validate=False)
+    gate_h.add(h_reverse_rate, hint="reverse_rate")
+    na_channel.add(gate_h)
+
+    na_channel_doc = component_factory(
+        "NeuroMLDocument", id="na_channel", notes="Na channel for HH neuron"
+    )
+    na_channel_fn = "HH_example_na_channel.nml"
+    na_channel_doc.add(na_channel)
+    na_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=na_channel_doc, nml2_file_name=na_channel_fn, validate=True
+    )
+
+    return na_channel_fn
+
+
+

Here, we define the two gates, m and h, with their forward and reverse rates and add them to the channel. +Next, we create a NeuroML document and save this channel (only this channel that we’ve just defined) to a NeuroML file and validate it. +So we now have our Na channel defined in a separate NeuroML file that can be used in multiple models and shared:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="na_channel">
+    <notes>Na channel for HH neuron</notes>
+    <ionChannelHH id="na_channel" species="na" conductance="10pS">
+        <notes>Sodium channel for HH cell</notes>
+        <gateHHrates id="m" instances="3">
+            <notes>m gate for na channel</notes>
+            <forwardRate type="HHExpLinearRate" rate="1per_ms" midpoint="-40mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV"/>
+        </gateHHrates>
+        <gateHHrates id="h" instances="1">
+            <notes>h gate for na channel</notes>
+            <forwardRate type="HHExpRate" rate="0.07per_ms" midpoint="-65mV" scale="-20mV"/>
+            <reverseRate type="HHSigmoidRate" rate="1per_ms" midpoint="-35mV" scale="10mV"/>
+        </gateHHrates>
+    </ionChannelHH>
+</neuroml>
+
+
+

The various rate equations (HHExpLinearRate, HHExpRate, HHSigmoidRate that can be used in the gate (here gateHHrates, but other forms such as gateHHtauInf and gateHHInstantaneous can be used) are defined in the NeuroML schema.

+

Also note that since we’ll want to include this file in other NeuroML files, we make the function return the name of the file. +This is an implementation detail, and there are other ways of doing this too. +We could have hard-coded this in all our functions or defined it as a global variable in the script for example. +If we were using object-oriented programming, we could have created a class and stored this information as a class or object variable.

+

The K and leak channels are defined in a similar way:

+
def create_k_channel():
+    """Create the K channel
+
+    This will create the K channel and save it to a file.
+    It will also validate this file.
+
+    :returns: name of the K channel file
+    """
+    k_channel = component_factory(
+        "IonChannelHH",
+        id="k_channel",
+        notes="Potassium channel for HH cell",
+        conductance="10pS",
+        species="k",
+        validate=False,
+    )
+    gate_n = component_factory(
+        "GateHHRates",
+        id="n",
+        instances="4",
+        notes="n gate for k channel",
+        validate=False,
+    )
+    n_forward_rate = component_factory(
+        "HHRate",
+        type="HHExpLinearRate",
+        rate="0.1per_ms",
+        midpoint="-55mV",
+        scale="10mV",
+    )
+    n_reverse_rate = component_factory(
+        "HHRate", type="HHExpRate", rate="0.125per_ms", midpoint="-65mV", scale="-80mV"
+    )
+    gate_n.add(n_forward_rate, hint="forward_rate", validate=False)
+    gate_n.add(n_reverse_rate, hint="reverse_rate")
+    k_channel.add(gate_n)
+
+    k_channel_doc = component_factory(
+        "NeuroMLDocument", id="k_channel", notes="k channel for HH neuron"
+    )
+    k_channel_fn = "HH_example_k_channel.nml"
+    k_channel_doc.add(k_channel)
+    k_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=k_channel_doc, nml2_file_name=k_channel_fn, validate=True
+    )
+
+    return k_channel_fn
+
+
+def create_leak_channel():
+    """Create a leak channel
+
+    This will create the leak channel and save it to a file.
+    It will also validate this file.
+
+    :returns: name of leak channel nml file
+    """
+    leak_channel = component_factory(
+        "IonChannelHH", id="leak_channel", conductance="10pS", notes="Leak conductance"
+    )
+    leak_channel_doc = component_factory(
+        "NeuroMLDocument", id="leak_channel", notes="leak channel for HH neuron"
+    )
+    leak_channel_fn = "HH_example_leak_channel.nml"
+    leak_channel_doc.add(leak_channel)
+    leak_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=leak_channel_doc, nml2_file_name=leak_channel_fn, validate=True
+    )
+
+    return leak_channel_fn
+
+
+
+

They are also saved in their own NeuroML files, which have also been validated. +The file for the K channel:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="k_channel">
+    <notes>k channel for HH neuron</notes>
+    <ionChannelHH id="k_channel" species="k" conductance="10pS">
+        <notes>Potassium channel for HH cell</notes>
+        <gateHHrates id="n" instances="4">
+            <notes>n gate for k channel</notes>
+            <forwardRate type="HHExpLinearRate" rate="0.1per_ms" midpoint="-55mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="0.125per_ms" midpoint="-65mV" scale="-80mV"/>
+        </gateHHrates>
+    </ionChannelHH>
+</neuroml>
+
+
+

For the leak channel:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="leak_channel">
+    <notes>leak channel for HH neuron</notes>
+    <ionChannelHH id="leak_channel" conductance="10pS">
+        <notes>Leak conductance</notes>
+    </ionChannelHH>
+</neuroml>
+
+
+
+
+

Declaring the cell#

+

Now that we have declared our ion channels, we can start constructing our cell in a different function.

+
def create_cell():
+    """Create the cell.
+
+    :returns: name of the cell nml file
+    """
+    # Create the nml file and add the ion channels
+    hh_cell_doc = NeuroMLDocument(id="cell", notes="HH cell")
+    hh_cell_fn = "HH_example_cell.nml"
+
+    # Define a cell
+    hh_cell = hh_cell_doc.add(
+        "Cell", id="hh_cell", notes="A single compartment HH cell"
+    )  # type: neuroml.Cell
+    hh_cell.info(show_contents=True)
+
+    # Channel density for Na channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="na_channels",
+        cond_density="120.0 mS_per_cm2",
+        erev="50.0 mV",
+        ion="na",
+        ion_channel="na_channel",
+        ion_chan_def_file=create_na_channel(),
+    )
+
+    # Channel density for k channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="k_channels",
+        cond_density="360 S_per_m2",
+        erev="-77mV",
+        ion="k",
+        ion_channel="k_channel",
+        ion_chan_def_file=create_k_channel(),
+    )
+    # Leak channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="leak_channels",
+        cond_density="3.0 S_per_m2",
+        erev="-54.3mV",
+        ion="non_specific",
+        ion_channel="leak_channel",
+        ion_chan_def_file=create_leak_channel(),
+    )
+
+    # Other membrane properties
+    hh_cell.add_membrane_property("SpikeThresh", value="-20mV")
+    hh_cell.set_specific_capacitance("1.0 uF_per_cm2")
+    hh_cell.set_init_memb_potential("-65mV")
+
+    hh_cell.set_resistivity("0.03 kohm_cm")
+
+    # We want a diameter such that area is 1000 micro meter^2
+    # surface area of a sphere is 4pi r^2 = 4pi diam^2
+    diam = math.sqrt(1000 / math.pi)
+    hh_cell.add_segment(
+        prox=[0, 0, 0, diam],
+        dist=[0, 0, 0, diam],
+        name="soma",
+        parent=None,
+        fraction_along=1.0,
+        group="soma_0",
+    )
+
+    hh_cell_doc.validate(recursive=True)
+    pynml.write_neuroml2_file(
+        nml2_doc=hh_cell_doc, nml2_file_name=hh_cell_fn, validate=True
+    )
+    return hh_cell_fn
+
+
+
+

Let us walk through this function:

+
    na_channel_doc.add(na_channel)
+    na_channel_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=na_channel_doc, nml2_file_name=na_channel_fn, validate=True
+    )
+
+    return na_channel_fn
+
+
+

We start by creating a new NeuroML document that we will use to save this cell, and adding the cell to it.

+

A Cell component has a number of child/children components that we need to now populate:

+
Cell -- Cell with  **segment** s specified in a  **morphology**  element along with details on its  **biophysicalProperties** . NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v**  of this cell represents the membrane potential in that isopotential segment.
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Cell are:
+* morphology_attr (class: NmlId, Optional)
+* biophysical_properties_attr (class: NmlId, Optional)
+* morphology (class: Morphology, Optional)
+        * Contents ('ids'/<objects>): 'morphology'
+
+* neuro_lex_id (class: NeuroLexId, Optional)
+* metaid (class: MetaId, Optional)
+* biophysical_properties (class: BiophysicalProperties, Optional)
+        * Contents ('ids'/<objects>): 'biophys'
+
+* id (class: NmlId, Required)
+        * Contents ('ids'/<objects>): hh_cell
+
+* notes (class: xs:string, Optional)
+        * Contents ('ids'/<objects>): A single compartment HH cell
+
+* properties (class: Property, Optional)
+* annotation (class: Annotation, Optional)
+
+
+

We can see that the morphology and biophysical properties components have already been initialised for us. +We now need to add the required components to them.

+

We begin with the biophysical properties. +Biophysical properties are themselves split into two:

+ +

Let us look at membrane properties first. +The schema shows that membrane properties has two child elements:

+ +

and three children elements:

+ +
+

Child elements vs Children elements

+

When an element specifies a Child subelement, it will only have one of these present (it could have zero). Children explicitly says that there can be zero, one or many subelements.

+
+

So, we start with the ion-channels which are distributed along the membrane with some density. +A number of helpful functions are available to us: add_channel_density, add_membrane_property, set_specific_capacitance, set_init_memb_potential: +For example, for the Na channels:

+
    # Channel density for Na channel
+    hh_cell.add_channel_density(
+        hh_cell_doc,
+        cd_id="na_channels",
+        cond_density="120.0 mS_per_cm2",
+        erev="50.0 mV",
+        ion="na",
+        ion_channel="na_channel",
+        ion_chan_def_file=create_na_channel(),
+    )
+
+
+

and similarly for the K and leak channels. +Now, since the ion-channels were created in other files, we need to make this document aware of their declarations. +To do this, reference the other files in the ion_chan_def_file argument of the add_channel_density method. +Under the hood, this will include the ion channel definition file we have created in this cell document using an IncludeType component. +Each document we want to include gets appended to the list of includes for the document.

+

Next, we add the other child and children elements: the Specific Capacitance, the Spike Threshold, the InitMembPotential. +This completes the membrane properties. +We then add the intracellular properties next: Resistivity.

+
    # Other membrane properties
+    hh_cell.add_membrane_property("SpikeThresh", value="-20mV")
+    hh_cell.set_specific_capacitance("1.0 uF_per_cm2")
+    hh_cell.set_init_memb_potential("-65mV")
+
+    hh_cell.set_resistivity("0.03 kohm_cm")
+
+
+

Next, we add the Morphology related information for our cell. +Here, we are only creating a single compartment cell with only one segment. +We will look into multi-compartment cells with more segments in later examples:

+
    diam = math.sqrt(1000 / math.pi)
+    hh_cell.add_segment(
+        prox=[0, 0, 0, diam],
+        dist=[0, 0, 0, diam],
+        name="soma",
+        parent=None,
+        fraction_along=1.0,
+        group="soma_0",
+    )
+
+
+

A segment has proximal and distal child elements which describe the extent of the segment. +These are described using a Point3DWithDiam object, which the add_segment function creates for us.

+

This completes our cell. +We add it to our NeuroML document, and save (and validate) it. +The resulting NeuroML file is:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="cell">
+    <notes>HH cell</notes>
+    <include href="HH_example_na_channel.nml"/>
+    <include href="HH_example_k_channel.nml"/>
+    <include href="HH_example_leak_channel.nml"/>
+    <cell id="hh_cell">
+        <notes>A single compartment HH cell</notes>
+        <morphology id="hh_cell_morph">
+            <segment id="0" name="soma">
+                <proximal x="0.0" y="0.0" z="0.0" diameter="17.841241161527712"/>
+                <distal x="0.0" y="0.0" z="0.0" diameter="17.841241161527712"/>
+            </segment>
+        </morphology>
+        <biophysicalProperties id="hh_b_prop">
+            <membraneProperties>
+                <channelDensity id="na_channels" ionChannel="na_channel" condDensity="120.0 mS_per_cm2" erev="50.0 mV" ion="na"/>
+                <channelDensity id="k_channels" ionChannel="k_channel" condDensity="360 S_per_m2" erev="-77mV" ion="k"/>
+                <channelDensity id="leak_channels" ionChannel="leak_channel" condDensity="3.0 S_per_m2" erev="-54.3mV" ion="non_specific"/>
+                <spikeThresh value="-20mV"/>
+                <specificCapacitance value="1.0 uF_per_cm2"/>
+                <initMembPotential value="-65mV"/>
+            </membraneProperties>
+            <intracellularProperties>
+                <resistivity value="0.03 kohm_cm"/>
+            </intracellularProperties>
+        </biophysicalProperties>
+    </cell>
+</neuroml>
+
+
+

We now have our cell defined in a separate NeuroML file, that can be re-used and shared.

+
+
+

Declaring the network#

+

We now use our cell in a network. +A network in NeuroML has multiple children elements: populations, projections, inputLists and so on. +Here we are going to only create a network with one cell, and an explicit input to the cell:

+
def create_network():
+    """Create the network
+
+    :returns: name of network nml file
+    """
+    net_doc = component_factory(
+        "NeuroMLDocument", id="network", notes="HH cell network"
+    )
+    net_doc_fn = "HH_example_net.nml"
+    net_doc.add("IncludeType", href=create_cell())
+    net = net_doc.add("Network", id="single_hh_cell_network", validate=False)
+
+    # Create a population: convenient to create many cells of the same type
+    pop = net.add(
+        "Population",
+        id="pop0",
+        notes="A population for our cell",
+        component="hh_cell",
+        size=1,
+    )
+
+    # Input
+    pulsegen = net_doc.add(
+        "PulseGenerator",
+        id="pg",
+        notes="Simple pulse generator",
+        delay="100ms",
+        duration="100ms",
+        amplitude="0.08nA",
+    )
+
+    exp_input = net.add("ExplicitInput", target="pop0[0]", input="pg")
+
+    net_doc.validate(recursive=True)
+
+    pynml.write_neuroml2_file(
+        nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True
+    )
+    return net_doc_fn
+
+
+

We start in the same way, by creating a new NeuroML document and including our cell file into it. +We then create a population comprising of a single cell. +We create a pulse generator as an explicit input, which targets our population. +Note that as the schema documentation for ExplicitInput notes, any current source (any component that extends basePointCurrent) can be used as an ExplicitInput.

+

We add all of these to the network and save (and validate) our network file. +The NeuroML file generated is below:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="network">
+    <notes>HH cell network</notes>
+    <include href="HH_example_cell.nml"/>
+    <pulseGenerator id="pg" delay="100ms" duration="100ms" amplitude="0.08nA">
+        <notes>Simple pulse generator</notes>
+    </pulseGenerator>
+    <network id="single_hh_cell_network">
+        <population id="pop0" component="hh_cell" size="1">
+            <notes>A population for our cell</notes>
+        </population>
+        <explicitInput target="pop0[0]" input="pg"/>
+    </network>
+</neuroml>
+
+
+
+
+

The generated NeuroML model#

+

Before we look at simulating the model, we can inspect our model to check for correctness. +All our NeuroML files were validated when they were created already, so we do not need to run this step again. +However, if required, this can be easily done:

+
pynml -validate HH_*nml
+
+
+

Next, we can visualise our model using the information noted in the visualising NeuroML models page (including the -v verbose option for more information on the cell):

+
pynml-summary HH_example_net.nml -v
+*******************************************************
+* NeuroMLDocument: network
+*
+*  IonChannelHH: ['k_channel', 'leak_channel', 'na_channel']
+*  PulseGenerator: ['pg']
+*
+*  Cell: hh_cell
+*    <Segment|0|soma>
+*      Parent segment: None (root segment)
+*      (0.0, 0.0, 0.0), diam 17.841241161527712um -> (0.0, 0.0, 0.0), diam 17.841241161527712um; seg length: 0.0 um
+*      Surface area: 1000.0 um2, volume: 2973.5401935879518 um3
+*    Total length of 1 segment: 0.0 um; total area: 1000.0 um2
+*
+*    Channel density: na_channels on all;       conductance of 120.0 mS_per_cm2 through ion chan na_channel with ion na, erev: 50.0 mV
+*      Channel is on <Segment|0|soma>,  total conductance: 1200.0 S_per_m2 x 1e-09 m2 = 1.2000000000000002e-06 S (1200000.0000000002 pS)
+*    Channel density: k_channels on all;        conductance of 360 S_per_m2 through ion chan k_channel with ion k, erev: -77mV
+*      Channel is on <Segment|0|soma>,  total conductance: 360.0 S_per_m2 x 1e-09 m2 = 3.6000000000000005e-07 S (360000.00000000006 pS)
+*    Channel density: leak_channels on all;     conductance of 3.0 S_per_m2 through ion chan leak_channel with ion non_specific, erev: -54.3mV
+*      Channel is on <Segment|0|soma>,  total conductance: 3.0 S_per_m2 x 1e-09 m2 = 3.0000000000000004e-09 S (3000.0000000000005 pS)
+*
+*    Specific capacitance on all: 1.0 uF_per_cm2
+*      Capacitance of <Segment|0|soma>, total capacitance: 0.01 F_per_m2 x 1e-09 m2 = 1.0000000000000001e-11 F (10.000000000000002 pF)
+*
+*  Network: single_hh_cell_network
+*
+*   1 cells in 1 populations
+*     Population: pop0 with 1 components of type hh_cell
+*
+*   0 connections in 0 projections
+*
+*   0 inputs in 0 input lists
+*
+*   1 explicit inputs (outside of input lists)
+*     Explicit Input of type pg to pop0(cell 0), destination: unspecified
+*
+*******************************************************
+
+
+

Since our model is a single compartment model with only one cell, it doesn’t have any 3D structure to visualise. +We can check the connectivity graph of the model:

+
pynml -graph 10 HH_example_net.nml
+
+
+

which will give us this figure:

+
+Level 10 network graph generated by pynml +
+

Fig. 14 Level 10 network graph generated by pynml#

+
+
+
+

Analysing channels#

+

Finally, we can analyse the ion channels that we’ve declared using the pynml-channelanalysis utility:

+
pynml-channelanalysis HH_example_k_channel.nml
+
+
+

This generates graphs to show the behaviour of the channel:

+
+
+
+
+
+Steady state behaviour of the K ion channel +
+

Fig. 15 Steady state behaviour of the K ion channel.#

+
+
+
+
+
+
+
+Time course of the K ion channel +
+

Fig. 16 Time course of the K ion channel.#

+
+
+
+
+
+
+

Similarly, we can get these for the Na channel also:

+
pynml-channelanalysis HH_example_na_channel.nml
+
+
+
+
+
+
+
+Steady state behaviour of the Na ion channel +
+

Fig. 17 Steady state behaviour of the Na ion channel.#

+
+
+
+
+
+
+
+Time course of the Na ion channel +
+

Fig. 18 Time course of the Na ion channel.#

+
+
+
+
+
+
+
+
+
+
+

Simulating the model#

+

Now that we have declared and inspected our network model and all its components, we can proceed to simulate it. +We do this in the main function:

+
def main():
+    """Main function
+
+    Include the NeuroML model into a LEMS simulation file, run it, plot some
+    data.
+    """
+    # Simulation bits
+    sim_id = "HH_single_compartment_example_sim"
+    simulation = LEMSSimulation(
+        sim_id=sim_id, duration=300, dt=0.01, simulation_seed=123
+    )
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_hh_cell_network")
+
+    # Recording information from the simulation
+    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+    simulation.add_column_to_output_file(
+        "output0", column_id="pop0[0]/v", quantity="pop0[0]/v"
+    )
+    simulation.add_column_to_output_file(
+        "output0", column_id="pop0[0]/iChannels", quantity="pop0[0]/iChannels"
+    )
+    simulation.add_column_to_output_file(
+        "output0",
+        column_id="pop0[0]/na/iDensity",
+        quantity="pop0[0]/biophys/membraneProperties/na_channels/iDensity/",
+    )
+    simulation.add_column_to_output_file(
+        "output0",
+        column_id="pop0[0]/k/iDensity",
+        quantity="pop0[0]/biophys/membraneProperties/k_channels/iDensity/",
+    )
+
+    # Save LEMS simulation to file
+    sim_file = simulation.save_to_file()
+
+    # Run the simulation using the default jNeuroML simulator
+    pynml.run_lems_with_jneuroml(sim_file, max_memory="2G", nogui=True, plot=False)
+    # Plot the data
+    plot_data(sim_id)
+
+
+

Here we first create a LEMSSimulation instance and include our network NeuroML file in it. +We must inform LEMS what the target of the simulation is. +In our case, it’s the id of our network, single_hh_cell_network:

+
    sim_id = "HH_single_compartment_example_sim"
+    simulation = LEMSSimulation(
+        sim_id=sim_id, duration=300, dt=0.01, simulation_seed=123
+    )
+    # Include the NeuroML model file
+    simulation.include_neuroml2_file(create_network())
+    # Assign target for the simulation
+    simulation.assign_simulation_target("single_hh_cell_network")
+
+
+

We also want to record some information, so we create an output file first with an id of output0:

+
    simulation.create_output_file(id="output0", file_name=sim_id + ".dat")
+
+
+

Now, we can record any quantity that is exposed by NeuroML (any exposure). +For example, we add a column for the membrane potential v of the cell which would be the 0th (and only) cell in our population pop0: pop0[0]/v. +We can also record the current in the channels: pop[0]/iChannels +We can also record the current density iDensity for the channels, so we also record these.

+
    simulation.add_column_to_output_file(
+        "output0", column_id="pop0[0]/v", quantity="pop0[0]/v"
+    )
+    simulation.add_column_to_output_file(
+        "output0", column_id="pop0[0]/iChannels", quantity="pop0[0]/iChannels"
+    )
+    simulation.add_column_to_output_file(
+        "output0",
+        column_id="pop0[0]/na/iDensity",
+        quantity="pop0[0]/biophys/membraneProperties/na_channels/iDensity/",
+    )
+    simulation.add_column_to_output_file(
+        "output0",
+        column_id="pop0[0]/k/iDensity",
+        quantity="pop0[0]/biophys/membraneProperties/k_channels/iDensity/",
+    )
+
+
+

We then save the LEMS simulation file, run our simulation with the default jNeuroML simulator.

+
+
+

Plotting the recorded variables#

+

To plot the variables that we recorded, we read the data and use the generate_plot utility function:

+
def plot_data(sim_id):
+    """Plot the sim data.
+
+    Load the data from the file and plot the graph for the membrane potential
+    using the pynml generate_plot utility function.
+
+    :sim_id: ID of simulaton
+
+    """
+    data_array = np.loadtxt(sim_id + ".dat")
+    pynml.generate_plot(
+        [data_array[:, 0]],
+        [data_array[:, 1]],
+        "Membrane potential",
+        show_plot_already=False,
+        save_figure_to=sim_id + "-v.png",
+        xaxis="time (s)",
+        yaxis="membrane potential (V)",
+    )
+    pynml.generate_plot(
+        [data_array[:, 0]],
+        [data_array[:, 2]],
+        "channel current",
+        show_plot_already=False,
+        save_figure_to=sim_id + "-i.png",
+        xaxis="time (s)",
+        yaxis="channel current (A)",
+    )
+    pynml.generate_plot(
+        [data_array[:, 0], data_array[:, 0]],
+        [data_array[:, 3], data_array[:, 4]],
+        "current density",
+        labels=["Na", "K"],
+        show_plot_already=False,
+        save_figure_to=sim_id + "-iden.png",
+        xaxis="time (s)",
+        yaxis="current density (A_per_m2)",
+    )
+
+
+

This generates the following graphs:

+
+
+
+
+
+Membrane potential +
+

Fig. 19 Membrane potential#

+
+
+
+
+
+
+
+Channel current +
+

Fig. 20 Channel current.#

+
+
+
+
+
+
+
+Channel current densities +
+

Fig. 21 Channel current densities#

+
+
+
+
+
+
+

This concludes out third example. +Here we have seen how to create, simulate, record, and visualise a single compartment Hodgkin-Huxley neuron. +In the next section, you will find an interactive notebook where you can play with this example.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/SingleNeuronExample.html b/Userdocs/SingleNeuronExample.html new file mode 100644 index 00000000..e3484aa4 --- /dev/null +++ b/Userdocs/SingleNeuronExample.html @@ -0,0 +1,1436 @@ + + + + + + + + + + + Simulating a regular spiking Izhikevich neuron — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Simulating a regular spiking Izhikevich neuron#

+
+

See also the interactive version.

+

Note: this is a more detailed description of the first example which is available as an interactive Juptyer notebook on the next page.

+
+

In this section, we wish to simulate a single regular spiking Izhikevich neuron ([Izh07]) and record/visualise its membrane potential (as shown in the figure below):

+
+Membrane potential for neuron recorded from the simulation +
+

Fig. 8 Membrane potential of the simulated regular spiking Izhikevich neuron.#

+
+
+

This plot, saved as example-single-izhikevich2007cell-sim-v.png, is generated using the following Python NeuroML script:

+
#!/usr/bin/env python3
+"""
+Simulating a regular spiking Izhikevich neuron with NeuroML.
+
+File: izhikevich-single-neuron.py
+"""
+
+from neuroml import NeuroMLDocument
+import neuroml.writers as writers
+from neuroml.utils import component_factory
+from neuroml.utils import validate_neuroml2
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+import numpy as np
+
+
+# Create a new NeuroML model document
+# component_factory: form one: provide name of NeuroML class as string
+# advantage of this form: do not need to import all the ComponentType classes
+# before using them
+nml_doc = component_factory("NeuroMLDocument", id="IzhSingleNeuron")
+# component_factory: form two: provide class as argument
+# nml_doc = component_factory(NeuroMLDocument, id="IzhSingleNeuron")
+
+# Inspect it:
+nml_doc.info()
+
+# Also see contents:
+nml_doc.info(show_contents=True)
+
+# Define the Izhikevich cell and add it to the model in the document
+# the `add` will create and validate the new component, and add it to the
+# parent (nml_doc)
+izh0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
+
+# Exercise 1: give wrong units of a parameter/parameters
+# Exercise 2: skip out a few parameters
+
+# Inspect the component
+izh0.info()
+
+# Inspect the component, also show all members:
+izh0.info(True)
+
+# inspect the document
+nml_doc.info(show_contents=True)
+
+# Create a network and add it to the model
+# net = component_factory("Network", id="IzNet")
+# Throws an error: why?
+# Because a Population is necessary in a Network, but we have not provided one.
+# Two workarounds:
+# - create population first, and pass that to component_factory here
+# - disable validation
+net = nml_doc.add("Network", id="IzNet", validate=False)
+
+# Create a population of defined cells and add it to the model
+size0 = 1
+pop0 = net.add("Population", id="IzhPop0", component=izh0.id, size=size0)
+
+# Define an external stimulus and add it to the model
+pg = nml_doc.add(
+    "PulseGenerator",
+    id="pulseGen_%i" % 0, delay="0ms", duration="1000ms",
+    amplitude="0.07 nA"
+)
+exp_input = net.add("ExplicitInput", target="%s[%i]" % (pop0.id, 0), input=pg.id)
+
+# Write the NeuroML model to a file
+nml_file = 'izhikevich2007_single_cell_network.nml'
+writers.NeuroMLWriter.write(nml_doc, nml_file)
+print("Written network file to: " + nml_file)
+
+# Validate the NeuroML model against the NeuroML schema
+validate_neuroml2(nml_file)
+
+################################################################################
+# The NeuroML file has now been created and validated. The rest of the code
+# involves writing a LEMS simulation file to run an instance of the model
+
+# Create a simulation instance of the model
+simulation_id = "example-single-izhikevich2007cell-sim"
+simulation = LEMSSimulation(sim_id=simulation_id,
+                            duration=1000, dt=0.1, simulation_seed=123)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+# Define the output file to store simulation outputs
+# we record the neuron's membrane potential
+simulation.create_output_file(
+    "output0", "%s.v.dat" % simulation_id
+)
+simulation.add_column_to_output_file("output0", 'IzhPop0[0]', 'IzhPop0[0]/v')
+
+# Save the simulation to a file
+lems_simulation_file = simulation.save_to_file()
+
+# Run the simulation using the jNeuroML simulator
+pynml.run_lems_with_jneuroml(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+# Load the data from the file and plot the graph for the membrane potential
+# using the pynml generate_plot utility function.
+data_array = np.loadtxt("%s.v.dat" % simulation_id)
+pynml.generate_plot(
+    [data_array[:, 0]], [data_array[:, 1]],
+    "Membrane potential", show_plot_already=False,
+    save_figure_to="%s-v.png" % simulation_id,
+    xaxis="time (s)", yaxis="membrane potential (V)"
+)
+
+
+
+

Declaring the model in NeuroML#

+
+

Python is the suggested programming language to use for working with NeuroML.

+

The Python NeuroML tools and libraries provide a convenient, easy to use interface to use NeuroML.

+
+

Let us step through the different sections of the Python script. +To start writing a model in NeuroML, we first create a NeuroMLDocument. +This “document” represents the complete model and is the top level container for everything that the model should contain.

+
nml_doc = component_factory("NeuroMLDocument", id="IzhSingleNeuron")
+
+
+

Let us define an Izhikevich cell that we will use to simulate a neuron. +The Izhikevich neuron model can take sets of parameters to exhibit different types of spiking behaviour. +Here, we define a component (object) of the general Izhikevich cell using parameters to show regular spiking.

+
izh0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
+
+
+
+

Now that the neuron has been defined and added to the document, we declare a network with a population of these neurons to create a network in a similar way. +Here, our model includes one network which includes only one population, which in turn only consists of a single neuron. +Once the network, its populations, and their neurons have been declared, we again add them to our model:

+
net = nml_doc.add("Network", id="IzNet", validate=False)
+
+# Create a population of defined cells and add it to the model
+size0 = 1
+pop0 = net.add("Population", id="IzhPop0", component=izh0.id, size=size0)
+
+
+

Question: why did we disable validation when we created the new network component?

+
net = nml_doc.add("Network", id="IzNet", validate=False)
+
+
+

Let us try creating a network without disabling validation:

+
net = nml_doc.add("Network", id="IzNet")
+
+
+

It will throw a validation error:

+
ValueError: Validation failed:
+- Number of values for populations is below the minimum allowed, expected at least 1, found 0
+
+
+

This is because a network must have at least one population for it to be valid. +To fix this, we can either create the population before the network, or we can disable validation. +Here we chose to disable validation because we knew we were immediately creating our population and adding it to our network.

+

Moving on, since we are providing a single input to the single cell in our network, we can add an ExplicitInput to our network. +See the supplementary section on the info function below to learn how you can find out that ExplicitInput could be used here.

+

The list of inputs included in the NeuroML specification can be found on the inputs page. +We use a pulse generator here, creating a new component and adding it to our NeuroML document. +To connect it to our neuron, we specify the neuron as the target using an explicit input.

+
# Define an external stimulus and add it to the model
+pg = nml_doc.add(
+    "PulseGenerator",
+    id="pulseGen_%i" % 0, delay="0ms", duration="1000ms",
+    amplitude="0.07 nA"
+)
+exp_input = net.add("ExplicitInput", target="%s[%i]" % (pop0.id, 0), input=pg.id)
+
+
+
+

This completes our model. +It includes a single network, with one population of one neuron that is driven by one pulse generator. +At this point, we can save our model to a file and validate it again to check if it conforms to the NeuroML schema (more on this later).

+
writers.NeuroMLWriter.write(nml_doc, nml_file)
+print("Written network file to: " + nml_file)
+
+# Validate the NeuroML model against the NeuroML schema
+validate_neuroml2(nml_file)
+
+
+

Note that the validation here will re-run the tests our component factory and other methods use, but it also runs a series of additional tests that can only be run on the complete model. +So, it is necessary to validate the model after it has been fully constructed.

+
+
+

Simulating the model#

+

Until now, we have just declared the model in NeuroML. We have not, however, included any information related to the simulation of this model, e.g. how long to run it for, what to save from the simulation etc.

+

With NeuroML v2, the information required to simulate the model is provided using a LEMS Simulation file. +We will not go into the details of LEMS just yet. +We will limit ourselves to the bits necessary to simulate our Izhikevich neuron only.

+

The following lines of code instantiate a new simulation with certain simulation parameters: duration, dt, simulation_seed. +Additionally, they also define what information is being recorded from the simulation. +In this case, we create an output file, and then add a new column to record the membrane potential v from our one neuron in the one population in it. +You can read more about recording from NeuroML simulations here.

+

Finally, like we had saved our NeuroML model to a file, we also save our LEMS document to a file.

+
simulation_id = "example-single-izhikevich2007cell-sim"
+simulation = LEMSSimulation(sim_id=simulation_id,
+                            duration=1000, dt=0.1, simulation_seed=123)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+# Define the output file to store simulation outputs
+# we record the neuron's membrane potential
+simulation.create_output_file(
+    "output0", "%s.v.dat" % simulation_id
+)
+simulation.add_column_to_output_file("output0", 'IzhPop0[0]', 'IzhPop0[0]/v')
+
+# Save the simulation to a file
+lems_simulation_file = simulation.save_to_file()
+
+
+

Finally, pyNeuroML also includes functions that allow you to run the simulation from the Python script itself:

+
pynml.run_lems_with_jneuroml(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+
+

Here, we are running our simulation using the jNeuroML simulator, which is bundled with pyNeuroML. +Since NeuroML is a well defined standard, models defined in NeuroML can also be run using other supported simulators.

+
+
+

Plotting the recorded membrane potential#

+

Once we have simulated our model and the data has been collected in the specified file, we can analyse the data. +pyNeuroML also includes some helpful functions to quickly plot various recorded variables. +The last few lines of code shows how the membrane potential plot at the top of the page is generated.

+
data_array = np.loadtxt("%s.v.dat" % simulation_id)
+pynml.generate_plot(
+    [data_array[:, 0]], [data_array[:, 1]],
+    "Membrane potential", show_plot_already=False,
+    save_figure_to="%s-v.png" % simulation_id,
+    xaxis="time (s)", yaxis="membrane potential (V)"
+)
+
+
+

On the next page, you will find an interactive Jupyter notebook where you can play with this example. +Click the “launch” button in the top right hand corner to run the notebook in a configured service. +You do not need to install any software on your computer to run these notebooks.

+
+
+

Supplementary information#

+

The sections here explain concepts that have been used above. +These will help give you a deeper understanding of NeuroML, so we do suggest you go through them also.

+
+

The generated NeuroML model XML#

+

Let us investigate the generated NeuroML XML file:

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="IzhSingleNeuron">
+    <izhikevich2007Cell id="izh2007RS0" C="100pF" v0="-60mV" k="0.7nS_per_mV" vr="-60mV" vt="-40mV" vpeak="35mV" a="0.03per_ms" b="-2nS" c="-50.0mV" d="100pA"/>
+    <pulseGenerator id="pulseGen_0" delay="0ms" duration="1000ms" amplitude="0.07 nA"/>
+    <network id="IzNet">
+        <population id="IzhPop0" component="izh2007RS0" size="1"/>
+        <explicitInput target="IzhPop0[0]" input="pulseGen_0"/>
+    </network>
+</neuroml>
+
+
+

NeuroML files are written in XML. +So, they consist of tags and attributes and can be processed by general purpose XML tools. +Each entity between chevrons is a tag: <..>, and each tag may have multiple attributes that are defined using the name=value format. +For example <neuroml ..> is a tag, that contains the id attribute with value NML2_SimpleIonChannel.

+
+

XML Tutorial

+

For details on XML, have a look through this tutorial.

+
+
+

Is this XML well-formed?

+

A NeuroML file needs to be both 1) well-formed, as in complies with the general rules of the XML language syntax, and 2) valid, i.e. contains the expected NeuroML specific tags/attributes.

+

Is the XML shown above well-formed? See for yourself. Copy the NeuroML file listed above and check it using an online XML syntax checker.

+
+

Let us step through this file to understand the different constructs used in it. +The first segment introduces the neuroml tag that includes information on the specification that this NeuroML file adheres to.

+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="IzhSingleNeuron">
+
+
+

The first attribute, xmlns defines the XML namespace. +All the tags that are defined for use in NeuroML are defined for use in the NeuroML namespace. +This prevents conflicts with other XML schemas that may use the same tags. +Read more on XML namespaces here.

+

The remaining lines in this snippet refer to the XML Schema that is defined for NeuroML. +XML itself does not define any tags, so any tags can be used in a general XML document. +Here is an example of a valid XML document, a simple HTML snippet:

+
<html>
+<head>
+<title>A title</title>
+</head>
+</html>
+
+
+

NeuroML, however, does not use these tags. +It defines its own set of standard tags using an XML Schema. +In other words, the NeuroML XML schema defines the structure and contents of a valid NeuroML document. +Various tools can then compare NeuroML documents to the NeuroML Schema to validate them.

+
+

Purpose of the NeuroML schema

+

The NeuroML Schema defines the structure and contents of a valid NeuroML document.

+
+

The xmlns:xi attribute documents that NeuroML has a defined XML Schema. +The next attribute, xsi:schemaLocation tells us the locations of the NeuroML Schema. +Here, two locations are provided:

+ +

We will look at the NeuroML schema in detail in later sections. +All NeuroML files must include the neuroml tag, and the attributes related to the NeuroML Schema. +The last attribute, id is the identification (or the name) of this particular NeuroML document.

+

The remaining part of the file is the declaration of the model and its dynamics:

+
    <izhikevich2007Cell id="izh2007RS0" C="100pF" v0="-60mV" k="0.7nS_per_mV" vr="-60mV" vt="-40mV" vpeak="35mV" a="0.03per_ms" b="-2nS" c="-50.0mV" d="100pA"/>
+    <pulseGenerator id="pulseGen_0" delay="0ms" duration="1000ms" amplitude="0.07 nA"/>
+    <network id="IzNet">
+        <population id="IzhPop0" component="izh2007RS0" size="1"/>
+        <explicitInput target="IzhPop0[0]" input="pulseGen_0"/>
+    </network>
+
+
+

The cell, is defined in the izhikevich2007Cell tag, which has a number of attributes as we saw before (see here for the schema definition):

+
    +
  • id: the name that we want to give to this cell. To refer to it later, for example,

  • +
  • v0: the initial membrane potential for the cell,

  • +
  • C: the leak conductance,

  • +
  • k: conductance per voltage,

  • +
  • vr: the membrane potential after a spike,

  • +
  • vt: the threshold membrane potential, to detect a spike,

  • +
  • vpeak: the peak membrane potential,

  • +
  • a, b, c, and d: are parameters of the Izhikevich neuron model.

  • +
+

Similarly, the pulseGenerator is also defined, and the network tag includes the population and explicitInput. +We observe that even though we have declared the entities, and the values for parameters that govern them, we do not state what and how these parameters are used. +This is because NeuroML is a declarative language that defines the structure of models. +We do not need to define how the dynamics of the different parts of the model are implemented. +As we will see further below, these are already defined in NeuroML.

+
+

NeuroML is a declarative language.

+

Users describe the various components of the model but do not need to worry about how they are implemented.

+
+

We have seen how an Izhikevich cell can be declared in NeuroML, with all its parameters.

+

As is evident, XML files are excellent for storing structured data, but may not be easy to write by hand. +However, NeuroML users are not expected to write in XML. +They should use the Python tools as demonstrated here.

+
+
+

The schema#

+

Given that NeuroML develops a standard and defines what tags and attributes can be used, let us see how these are defined for the Izhikevich cell. +The Izhikevich cell is defined in version 2 of the NeuroML schema here:

+
    <xs:complexType name="Izhikevich2007Cell">
+        <xs:complexContent>
+            <xs:extension base="BaseCellMembPotCap">
+                <xs:attribute name="v0" type="Nml2Quantity_voltage" use="required"/>
+                <xs:attribute name="k" type="Nml2Quantity_conductancePerVoltage" use="required"/>
+                <xs:attribute name="vr" type="Nml2Quantity_voltage" use="required"/>
+                <xs:attribute name="vt" type="Nml2Quantity_voltage" use="required"/>
+                <xs:attribute name="vpeak" type="Nml2Quantity_voltage" use="required"/>
+                <xs:attribute name="a" type="Nml2Quantity_pertime" use="required"/>
+                <xs:attribute name="b" type="Nml2Quantity_conductance" use="required"/>
+                <xs:attribute name="c" type="Nml2Quantity_voltage" use="required"/>
+                <xs:attribute name="d" type="Nml2Quantity_current" use="required"/>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+
+

The xs: prefix indicates that these are all part of an XML Schema. +The Izhikevich cell and all its parameters are defined in the schema. +As we saw before, parameters of the model are defined as attributes in NeuroML files. +So, here in the schema, they are also defined as attributes of the complexType that the schema describes. +The schema also specifies which of the parameters are necessary, and what their dimensions (units) are using the use and type properties.

+

This schema gives us all the information we need to describe an Izhikevich cell in NeuroML. +Using the specification in the Schema, any number of Izhikevich cells can be defined in a NeuroML file with the necessary parameter sets to create networks of Izhikevich cells.

+
+
+

The generated LEMS XML#

+

The generated LEMS simulation file is shown below:

+
<Lems>
+
+    <!-- 
+
+        This LEMS file has been automatically generated using PyNeuroML v1.1.13 (libNeuroML v0.5.8)
+
+     -->
+
+    <!-- Specify which component to run -->
+    <Target component="example-single-izhikevich2007cell-sim"/>
+
+    <!-- Include core NeuroML2 ComponentType definitions -->
+    <Include file="Cells.xml"/>
+    <Include file="Networks.xml"/>
+    <Include file="Simulation.xml"/>
+
+    <Include file="izhikevich2007_single_cell_network.nml"/>
+
+    <Simulation id="example-single-izhikevich2007cell-sim" length="1000ms" step="0.1ms" target="IzNet" seed="123">  <!-- Note seed: ensures same random numbers used every run -->
+        <OutputFile id="output0" fileName="example-single-izhikevich2007cell-sim.v.dat">
+            <OutputColumn id="IzhPop0[0]" quantity="IzhPop0[0]/v"/>
+        </OutputFile>
+
+    </Simulation>
+
+</Lems>
+
+
+

Similar to NeuroML, a LEMS Simulation file also has a well defined structure, i.e., a set of valid tags which define the contents of the LEMS file. +We observe that whereas the NeuroML tags were related to the modelling parameters, the LEMS tags are related to simulation. +We also note that our NeuroML model has been “included” in the LEMS file, so that all entities defined there are now known to the LEMS simulation also. +Like NeuroML, users are not expected to write the LEMS XML component by hand. +They should continue to use the NeuroML Python tools.

+
+
+

The component_factory() function#

+

In the code above, we’ve used the component_factory utility function that is included in the neuroml.utils module. +This is, as the name notes, a “factory function”. +When we provide the name of a NeuroML component type (the Python class) to it +as the first argument along with any parameters, it will create a new component +(Python object) and return it to us to use, after running a few checks under +the hood:

+
    +
  • is the created component valid?

  • +
  • are all the necessary parameters set?

  • +
  • are any extra parameters given?

  • +
+

We will see some of these checks in action later as we create more components for our model.

+

The component_factory can accept two forms. +We can either pass the component type (class) to the function, or we can pass its name as a string. +The difference is that we do not need to import the class in our script before using it if we specify its name as a string. +The component factory function will import the class for us for us internally. +Either form works, so you can choose which you prefer. +It is important to only remain consistent and use one form to aid readability.

+
+
+

The add() function#

+

We’ve used another utility method in the code above: add. +The add method calls the component_factory for us internally to create a new object of the required component.

+

We could also use the component_factory, followed by add, which would result in the same thing:

+
izh0 = component_factory(
+    "Izhikevich2007Cell",
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
+nml_doc.add(izh0)
+
+
+

In fact, we could do it all without using either method:

+
# from neuroml import Izhikevich2007Cell
+izh0 = neuroml.Izhikevich2007Cell(
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
+nml_doc.izhikevich2007_cells.append(izh0)
+
+
+

This last form is not suggested because here, the extra checks that the component_factory and add methods run are not carried out. +You also need to know the name of the variable in the nml_doc object to be able to append to it. +The output of the info method will list all the member names, but the add method inspects the parent component and places the child in the right place for us.

+

An exercise here would be to try providing invalid arguments to the add or component_factory methods. +For example:

+
    +
  • try giving the wrong units for a parameter

  • +
  • try leaving out a parameter

  • +
+

What happens?

+

For example, I have used the wrong units for the d parameter here, ms instead of pA:

+
# or
+# izh0 = component_factory(
+izh0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100ms")
+
+
+

and it will throw a ValueError telling us that this does not match the expected string for d:

+
ValueError: Validation failed:
+- Value "100ms" does not match xsd pattern restrictions: [['^(-?([0-9]*(\\.[0-9]+)?)([eE]-?[0-9]+)?[\\s]*(A|uA|nA|pA))$']]
+
+
+

The specific error here includes the “pattern restrictions” (regular expression) for valid values of the d parameter. +There are a number of tutorials on regular expressions on the internet that you can use to learn more about the meaning of the provided pattern restriction. +The one restriction that we are interested in here is that the value of d must end in one of A, uA, nA, or pA. +Anything else will result in an invalid value, and the factory will throw a ValueError.

+

The NeuroML specification declares valid units for all its components. +This allows us to validate models and components while building the model—even before we have a complete model that we want to simulate. +In fact, NeuroML also defines a list of units and dimensions that can be used.

+
+

Units in NeuroML

+

NeuroML defines a standard set of units that can be used in models. +Learn more about units and dimensions in NeuroML and LEMS here.

+
+
+
+

The info() function#

+

Now that we have a document, what if we want to inspect it to see what components it can hold, and what its current contents are? +Each NeuroML component type includes the info function that gives us a quick summary of information about the component:

+
nml_doc.info()
+
+# Also see contents:
+nml_doc.info(show_contents=True)
+
+
+

The output will be of this form:

+
Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for NeuroMLDocument are:
+* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)
+* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)
+* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)
+* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)
+* IF_curr_alpha (class: IF_curr_alpha, Optional)
+* alpha_synapses (class: AlphaSynapse, Optional)
+...
+
+
+

This shows all the valid NeuroML components that the top level NeuroMLDocument component can directly contain. +It also tells us the component type (class) corresponding to the component (object). +It also tells us whether this component is optional or required.

+

In the second form, where we also pass show_contents=True, it will also show the contents of each member if any. +We can use this to inspect our created Izhikevich cell component:

+
izh0.info(True)
+
+
+

The output will be:

+
Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Izhikevich2007Cell are:
+* annotation (class: Annotation, Optional)
+* b (class: Nml2Quantity_conductance, Required)
+        * Contents ('ids'/<objects>): -2nS
+
+* c (class: Nml2Quantity_voltage, Required)
+        * Contents ('ids'/<objects>): -50.0mV
+
+* d (class: Nml2Quantity_current, Required)
+        * Contents ('ids'/<objects>): 100pA
+
+* C (class: Nml2Quantity_capacitance, Required)
+        * Contents ('ids'/<objects>): 100pF
+
+* v0 (class: Nml2Quantity_voltage, Required)
+        * Contents ('ids'/<objects>): -60mV
+
+* k (class: Nml2Quantity_conductancePerVoltage, Required)
+        * Contents ('ids'/<objects>): 0.7nS_per_mV
+
+* vr (class: Nml2Quantity_voltage, Required)
+        * Contents ('ids'/<objects>): -60mV
+
+* neuro_lex_id (class: NeuroLexId, Optional)
+* metaid (class: MetaId, Optional)
+* vt (class: Nml2Quantity_voltage, Required)
+        * Contents ('ids'/<objects>): -40mV
+
+* id (class: NmlId, Required)
+        * Contents ('ids'/<objects>): izh2007RS0
+
+* notes (class: xs:string, Optional)
+* vpeak (class: Nml2Quantity_voltage, Required)
+        * Contents ('ids'/<objects>): 35mV
+
+* properties (class: Property, Optional)
+* a (class: Nml2Quantity_pertime, Required)
+        * Contents ('ids'/<objects>): 0.03per_ms
+
+
+

We can see that all the required parameters are correctly set for this component.

+

We can also inspect the full document:

+
nml_doc.info(show_contents=True)
+
+
+

Try running this at the beginning of the script right after creating the document, and at the end when the model has been completed. +You should notice a major change, that our cell has been correctly added to the document.

+
...
+* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)
+*         * Contents ('ids'/<objects>): ['izh2007RS0']
+*
+...
+
+
+

The info() function is very useful to see what components can belong to another. +For example, to see what components can be added to our net network, we can run this:

+
net.info()
+
+Network -- Network containing:  **population** s ( potentially of type  **populationList** , and so specifying a list of cell  **location** s );  **projection** s ( with lists of  **connection** s ) and/or  **explicitConnection** s; and  **inputList** s ( with lists of  **input** s ) and/or  **explicitInput** s. Note: often in NeuroML this will be of type  **networkWithTemperature**  if there are temperature dependent elements ( e. g. ion channels ).
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for Network are:
+* metaid (class: MetaId, Optional)
+* notes (class: xs:string, Optional)
+* properties (class: Property, Optional)
+* annotation (class: Annotation, Optional)
+* type (class: networkTypes, Optional)
+* temperature (class: Nml2Quantity_temperature, Optional)
+* neuro_lex_id (class: NeuroLexId, Optional)
+* spaces (class: Space, Optional)
+* regions (class: Region, Optional)
+* extracellular_properties (class: ExtracellularPropertiesLocal, Optional)
+* populations (class: Population, Required)
+* cell_sets (class: CellSet, Optional)
+* id (class: NmlId, Required)
+* synaptic_connections (class: SynapticConnection, Optional)
+* projections (class: Projection, Optional)
+* electrical_projections (class: ElectricalProjection, Optional)
+* continuous_projections (class: ContinuousProjection, Optional)
+* explicit_inputs (class: ExplicitInput, Optional)
+* input_lists (class: InputList, Optional)
+
+
+

This tells us what net can contain. +For setting the input, for example, it would seem that we should use one of either ExplicitInput or InputList here. +The ctinfo function can be used to get more information about these (next).

+
+
+

The ctinfo() function#

+

There are multiple ways of getting information on a component type. +The first, of course, is to look at the schema documentation online. +The documentation for ExplicitInput is here, and for InputList is here. +The schema documentation will also include examples of usage for most component types under the “Usage:Python” tab.

+

neuroml includes the ctinfo() utility function, that like the info() method, provides information about component types (ct in ctinfo stands for component type). +Note that component types are classes and the info() method cannot be used on them. +It can only be used once objects have been created from the component type classes.

+

So, we could do (create a new dummy object of the class and call info() on it):

+
neuroml.ExplicitInput().info()
+
+
+

but ctinfo will do this for us:

+
from neuroml.utils import ctinfo
+ctinfo("ExplicitInput")
+# or the second form:
+# ctinfo(neuroml.ExplicitInput)
+ExplicitInput -- An explicit input ( anything which extends  **basePointCurrent**  ) to a target cell in a population
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for ExplicitInput are:
+* destination (class: xs:string, Optional)
+* target (class: xs:string, Required)
+* input (class: xs:string, Required)
+
+
+ctinfo("InputList")
+InputList -- An explicit list of  **input** s to a **population.**
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid members for InputList are:
+* populations (class: NmlId, Required)
+* component (class: NmlId, Required)
+* input (class: Input, Optional)
+* input_ws (class: InputW, Optional)
+* id (class: NmlId, Required)
+
+
+

Finally, for completeness, we can also get information from the API documentation for libNeuroML here. +Since this is documentation that is “embedded” in the Python classes, we can also use the Python in-built help function to see it:

+
help(neuroml.ExplicitInput)
+Help on class ExplicitInput in module neuroml.nml.nml:
+
+class ExplicitInput(BaseWithoutId)
+ |  ExplicitInput(target: 'one str (required)' = None, input: 'one str (required)' = None, destination: 'one str (optional)' = None, gds_collector_=None, **kwargs_)
+ |  
+ |  ExplicitInput -- An explicit input ( anything which extends  **basePointCurrent**  ) to a target cell in a population
+ |  
+ ...
+
+
+
+help(neuroml.InputList)
+Help on class InputList in module neuroml.nml.nml:
+
+class InputList(Base)
+ |  InputList(id: 'one NonNegativeInteger (required)' = None, populations: 'one NmlId (required)' = None, component: 'one NmlId (required)' = None, input: 'list of Input(s) (optional)' = None, input_ws: 'list of InputW(s) (optional)' = None, gds_collector_=None, **kwargs_)
+ |  
+ |  InputList -- An explicit list of  **input** s to a **population.**
+ ...
+
+
+

The information provided by the different sources will be similar, but ctinfo() is perhaps the most NeuroML specific (whereas the Python help() function provides Python language related information also.)

+
+

Use an integrated development environment (IDE):

+

IDEs make programming easier. For example, a good IDE will show you the documentation that the help Python function shows.

+
+

Another useful function is the ctparentinfo() function. +Like info() it provides some information about the component/object:

+
ctparentinfo("InputList")
+InputList -- An explicit list of  **input** s to a **population.**
+
+Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.
+
+Valid parents for InputList are:
+* Network
+        * input_lists (class: InputList, Optional)
+
+
+

This tells us that components of type InputList can be added to components of the Network type, in the input_list member. +Of course, we will use the add function in our network object net, and that will add the component to the correct member.

+
+
+

The validate() function#

+

We can check whether each component is valid using the validate function that each component has. +For example:

+
net.validate()
+
+
+

This function does not return anything if the component is valid. +(Technically, if a function does not return anything in Python, it returns +None by default, so this returns None if the component is valid.) +However, if it is not valid, it will throw a ValueError.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/MatLab.html b/Userdocs/Software/MatLab.html new file mode 100644 index 00000000..04f803e1 --- /dev/null +++ b/Userdocs/Software/MatLab.html @@ -0,0 +1,721 @@ + + + + + + + + + + + MatLab NeuroML Toolbox — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

MatLab NeuroML Toolbox

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

MatLab NeuroML Toolbox#

+

The NeuroML 2 Toolbox for MATLAB facilitates access to the Java NeuroML 2 API functionality (jNeuroML) directly within Matlab.

+
+

Quick start#

+

Please install jNeuroML following the instructions provided here. +Run Matlab and run the prefdir command to find the location of your preferences folder. +Create a file javaclasspath.txt within that folder containing, on a single line, the full path to the jNeuroML-<version>-jar-with-dependencies.jar from jNeuroML.

+

Restart Matlab, and you will be able to access jNeuroML classes. +You can test your setup by validating an example file:

+
import org.neuroml.model.util.NeuroML2Validator
+file = java.io.File('/full/path/to/model.nml');
+validator = NeuroML2Validator();
+validator.validateWithTests(file);
+disp(validator.getValidity())
+
+
+
+
+

Documentation#

+

Please refer to the jNeuroML documentation for information on the Java NeuroML API. +Examples on using the Matlab toolbox are available here.

+
+
+

Getting help#

+

For any questions regarding the NeuroML Matlab toolbix, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

The NeuroML Matlab toolbox is developed on GitHub at NeuroML/NeuroMLToolbox.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/NeuroML_API.html b/Userdocs/Software/NeuroML_API.html new file mode 100644 index 00000000..7046270c --- /dev/null +++ b/Userdocs/Software/NeuroML_API.html @@ -0,0 +1,722 @@ + + + + + + + + + + + NeuroML C++ API — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NeuroML C++ API

+ +
+ +
+
+ + + + +
+ +
+

NeuroML C++ API#

+

A C++ API for NeuroML.

+
+

Quick start#

+

The C++ API is generated from the NeuroML specification using the CodeSynthesis XSD XML Schema to C++ data binding compiler. +The C++ API needs to be compiled from source. +Please refer to the instructions in the Readme document for instructions on building and installing the API.

+
+
+

Documentation#

+

For information on the generated C++ structure, please see the XSD user manual.

+
+

API documentation#

+

API documentation for the C++ API can be found here. +It can also be generated while building the API from source, as documented in the Readme.

+
+
+
+

Getting help#

+

For any questions regarding the C++ NeuroML API, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

The C++ NeuroML API is developed on GitHub at NeuroML/NeuroML_API under the MIT license.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/NeuroMLlite.html b/Userdocs/Software/NeuroMLlite.html new file mode 100644 index 00000000..60dba5f4 --- /dev/null +++ b/Userdocs/Software/NeuroMLlite.html @@ -0,0 +1,826 @@ + + + + + + + + + + + NeuroMLlite — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

NeuroMLlite#

+

NeuroMLlite is a common framework for reading/writing/generating network specifications which builds on NeuroML 2. +It is intended to provide a high level specification which can be used to generate networks in NeuroML and many other formats—including graphical and in neuronal simulator formats.

+ +
+

Quick start#

+
+

Install Python#

+

Python is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official installation instructions to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is here.

+
+
+

Install NeuroMLlite with pip#

+ +

The easiest way to install the latest version of libNeuroML is using the default Python package manager, pip:

+
pip install neuromllite
+
+
+
+
+

Installation on Fedora Linux#

+

On Fedora Linux systems, the NeuroFedora community provides pyNeuroML as a package in their extras repository and can be installed using the following commands:

+
sudo dnf copr enable @neurofedora/neurofedora-extra
+sudo dnf install python3-neuromllite
+
+
+
+
+
+

Documentation#

+

Along with a Python API, NeuroMLlite also provides a graphical user interface nmllite-ui that can be used to create network models and export or simulate them using different simulators supported by NeuroML.

+
nmllite-ui
+
+NMLlite-UI v0.2.4: A GUI for loading NeuroMLlite files
+
+Usage:
+    nmllite-ui Sim_xxx.json
+         Load a NeuroMLlite file containing a Simulation, which refers to the Network to run
+
+
+
+Screenshot of NeuroMLlite UI showing an example simulation. +
+

Fig. 65 Screenshot of NeuroMLlite UI showing an example simulation#

+
+
+
+

API documentation#

+ +

The NeuroMLlite API is self documented. +You can use Python’s in-built documentation viewer pydoc to view the documentation for any of the package’s modules and their functions:

+
Help on package neuromllite:
+
+NAME
+    neuromllite
+
+PACKAGE CONTENTS
+    ArborHandler
+    BBPConnectomeReader
+    BaseTypes
+    ConnectivityHandler
+    DefaultNetworkHandler
+    GraphVizHandler
+    MatrixHandler
+    NetworkGenerator
+    NeuronHandler
+    PsyNeuLinkHandler
+    PsyNeuLinkReader
+    PyNNHandler
+    SonataHandler
+    SonataReader
+    gui (package)
+    sweep (package)
+    utils
+
+...
+
+
+

Most IDEs are able to show you this information as you use them in your Python scripts.

+

A number of examples showing how the NeuroMLlite Python API is to be used are also included in the GitHub repository. +For instance, Example4.py can be run in the following ways to generate different representations of the created network model. +Please see the Readme file included in the repository for more example usage.

+
python Example4.py                  # Generate the network in JSON
+python Example4.py -nml             # Generate the network in NeuroML2
+python Example4.py -jnml            # Generate the network in NeuroML2 & run using jNeuroML
+python Example4.py -jnmlnetpyne     # Generate the network in NeuroML2 & run using NetPyNE
+python Example4.py -jnmlnrn         # Generate the network in NeuroML2 & run using NEURON
+python Example4.py -netpyne         # Generate & run the network directly in NetPyNE
+python Example4.py -pynnnest        # Generate & run the network in NEST using PyNN
+python Example4.py -pynnnrn         # Generate & run the network in NEURON using PyNN
+python Example4.py -pynnbrian       # Generate & run the network in Brian using PyNN
+...
+
+
+
+
+
+

Getting help#

+

For any questions regarding NeuroMLlite, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

pyNeuroML is developed on GitHub at NeuroML/NeuroMLlite under the LPGL-3.0 license. +The repository contains the complete source code along with instructions on building/installing pyNeuroML. +Please follow the instructions there to build pyNeuroML from source.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Software.html b/Userdocs/Software/Software.html new file mode 100644 index 00000000..3325d9ff --- /dev/null +++ b/Userdocs/Software/Software.html @@ -0,0 +1,726 @@ + + + + + + + + + + + Software and Tools — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Software and Tools#

+
+

Core NeuroML Tools#

+

The NeuroML initiative supports a core set of libraries (mainly in Python and Java) to enable the creation/validation/analysis/simulation of NeuroML models as well as to facilitate adding support for the language to other applications.

+
+jNeuroML and pyNeuroML +
+

Fig. 62 Relationship between jLEMS, jNeuroML, the NeuroML 2 LEMS definitions, libNeuroML, pyLEMS and pyNeuroML.#

+
+
+
+

Python based applications#

+

For most users, pyNeuroML will provide all of the key functionality for building, validating, simulating, visualising, and converting NeuroML 2 and LEMS models. It builds on libNeuroML and pyLEMS and bundles all of the functionality of jNeuroML to provide access to this through a Python interface.

+
+
+

Java based applications#

+

jNeuroML (for validating, simulating and converting NeuroML 2 models) and jLEMS (for simulating LEMS models) are the key applications +created in Java for supporting NeuroML 2/LEMS.

+
+
+

NeuroML support in other languages#

+

There are preliminary APIs for using NeuroML in C++ and MATLAB.

+
+
+
+

Other NeuroML supporting applications#

+

Many other simulators, applications and libraries support NeuroML. See here for more details.

+

A number of databases and neuroinformatics initiatives support NeuroML as a core interchange format. See here for more details.

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/SupportingTools.html b/Userdocs/Software/SupportingTools.html new file mode 100644 index 00000000..dd54aace --- /dev/null +++ b/Userdocs/Software/SupportingTools.html @@ -0,0 +1,1015 @@ + + + + + + + + + + + Tools and resources with NeuroML support — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Tools and resources with NeuroML support#

+

Apart from the core NeuroML tools (e.g. pyNeuroML, jNeuroML) there are many +other applications, libraries and databases which support NeuroML 2 and LEMS.

+

h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h

+

These tools take a number of different approaches to adding NeuroML support, from dealing with the format natively to allowing import/export of (subsets of) the language, to an external application generating scripts/code for use in the simulator.

+
+

Please help us keep this page up to date.

+

Tools listed here may have moved to new locations, or may no longer be maintained, and others may be missing. +Please file issues if you can help update this information.

+
+
+

Applications with NeuroML support#

+
+

NEURON#

+

NEURON logo

+

The NEURON simulation environment is one of the main target platforms for a standard facilitating exchange of neuronal models. jNeuroML can be used to convert NeuroML2/LEMS models to NEURON. NEURON simulations can also be generated from NeuroML model components by neuroConstruct.

+

See also NetPyNE, which builds on NEURON.

+

There is a dedicated page on NEURON/NeuroML interactions here.

+
+
+

NetPyNE#

+

NetPyNE logo

+

NetPyNE is a Python package to facilitate the development, simulation, parallelization, analysis, and optimization of biological neuronal networks using the NEURON simulator. NetPyNE can import from and export to NeuroML. NetPyNE also provides a web based Graphical User Interface.

+

There is a dedicated page on NetPyNE/NeuroML interactions here.

+
+
+

neuroConstruct#

+

Neuroconstruct logo

+

neuroConstruct is a Java based application for constructing 3D networks of biologically realistic neurons. The current version can generate code for the NEURON, GENESIS, PSICS and PyNN platforms and also provides import/export support for MorphML, ChannelML and NetworkML (from NeuroML v1) and for NeuroMLv2 cells and networks.

+

More info on the support for NeuroML in neuroConstruct is available here.

+
+
+

GENESIS#

+

GENESIS logo

+

GENESIS is a commonly used neuronal simulation environment and was a main target platform for the NeuroMLv1 specifications. Full GENESIS simulations can be generated from NeuroMLv1 model components by neuroConstruct.

+

Due to the lack of active development of GENESIS, support for mapping to GENESIS in NeuroMLv2 has been deprecated in favour of MOOSE.

+
+
+

MOOSE#

+

MOOSE logo

+

MOOSE is the Multiscale Object-Oriented Simulation Environment. It is the base and numerical core for large, detailed multi-scale simulations that span computational neuroscience and systems biology. It is based on a complete reimplementation of the GENESIS 2 core.

+

More information on running NeuroML models in MOOSE can be found here.

+

There is a dedicated page on MOOSE/NeuroML interactions here.

+
+
+

BRIAN#

+

Brian logo

+

Brian is an easy to use, Python based simulator of spiking networks.

+

There is a dedicated page on Brian/NeuroML interactions here.

+
+
+

EDEN#

+

EDEN is a recently developed simulation engine which incorporates native NeuroML 2 support from the start.

+

Initial tests of using EDEN with NeuroML models and example code can be found here.

+

There is a dedicated page on EDEN/NeuroML interactions here.

+
+
+

Arbor#

+

Arbor logo

+

Arbor is a high performance multicompartmental neural simulation library. Addition of support for NeuroML2 and LEMS is under active development. +See here.

+

Example code for interactions between NeuroML models and Arbor can be found here.

+

There is a dedicated page on Arbor/NeuroML interactions here.

+
+
+

PyNN#

+

PyNN logo

+

PyNN is a Python package for simulator independent specification of neuronal network models. Model code can be developed using the PyNN API and then run using NEURON, NEST or Brian. The developed model also can be stored as a NeuroML document. The latest version of neuroConstruct can be used to generate executable scripts for PyNN based simulators based on NeuroML components, although the majority of multicompartmental conductance based models which are available in neuroConstruct are outside the current scope of the PyNN API.

+

More info on the latest support for running NeuroML models in PyNN and vice versa can be found here.

+
+
+

NEST#

+

NEST logo

+

NEST is a simulator for spiking neural network models that focuses on the dynamics, size and structure of neural systems rather than on the exact morphology of individual neurons.

+

There is a dedicated page on NEST/NeuroML interactions here.

+
+
+

OpenWorm#

+

OpenWorm logo

+

The OpenWorm project aims to create a simulation platform to build digital in-silico living systems, starting with a C. elegans virtual organism simulation. The simulations and associated tools are being developed in a fully open source manner. NeuroML is being used for the description of the 302 neurons in the worm’s nervous system, both for morphological description of the cells and their electrical properties.

+

The c302 subproject in OpenWorm has the latest developments in the NeuroML version of the worm nervous system.

+

Members of the OpenWorm project are also creating a general purpose neuronal simulator (for both electrical and physical simulations) which will have parallelism and native support for NeuroML built in from the start (see Geppetto.

+
+
+

Model Description Format (MDF)#

+

MDF logo

+

ModECI Model Description Format (MDF) is an open source, community-supported standard and associated library of tools for expressing computational models in a form that allows them to be exchanged between diverse programming languages and execution environments, with a particular focus on machine learning, artificial intelligence and computational neuroscience.

+

There will be full compatibility between NeuroML and MDF for specifying neuronal models. See here for ongoing work in this direction.

+
+
+

The Virtual Brain#

+

TVB logo

+

The Virtual Brain (TVB) offers a simulation environment for large-scale brain networks. It allows network properties, in particular the brain’s structural connectivity, to be incorporated into models, and so TVB can simulate whole brain behaviour as is commonly observed in clinical scanners (e.g. EEG, MEG, fMRI).

+

Initial work mapping networks in TVB to/from NeuroML 2 and LEMS can be found here. See also the work of the INCF Network Specification Working Group in this area.

+
+
+

LFPy#

+

LFPy logo

+

LFPy is a Python package for calculation of extracellular potentials from multicompartment neuron models. It relies on the NEURON simulator and uses the Python interface it provides. LFPy provides a set of easy to use Python classes for setting up the model, running simulations and calculating the extracellular potentials arising from activity in the model neuron. Initial support for loading of NeuroML morphologies has been added.

+
+
+

BioSimulators#

+

BioSimulators logo

+

BioSimulators provides a registry and platform supporting a broad range of modeling frameworks, model formats, simulation algorithms, and simulation tools.

+

See for example https://biosimulators.org/simulators/pyneuroml/latest.

+
+
+

N2A#

+

“Neurons to Algorithms” (N2A) is a language for modeling neural systems, along with a software tool for editing models and simulating them.

+

There is a dedicated page on N2A/NeuroML interactions here.

+
+
+

NeuronLand#

+

NeuronLand logo

+

NeuronLand provides NLMorphologyConverter, which is a command line program for converting between over 20 different 3D neuron morphology formats, and NLMorphologyViewer, which provides a simple interface for viewing these data. Both of these tools provide import and export of MorphML.

+
+
+

CX3D#

+

CX3D logo

+

CX3D is a tool for simulating the growth of cortex in 3D. There was a preliminary implementation of export of generated networks to NeuroML in CX3D.

+
+
+

TREES toolbox#

+

Trees logo

+

The TREES toolbox is an application in MATLAB which allows: automatic reconstruction of neuronal branching from microscopy image stacks and generation of synthetic axonal and dendritic trees; visualisation, editing and analysis of neuronal trees; comparison of branching patterns between neurons; and investigation of how dendritic and axonal branching depends on local optimization of total wiring and conduction distance.

+

The latest version of the TREES toolbox includes basic functionality for exporting cells in NeuroML v1.x Level 1 (MorphML) or as a NeuroML v2alpha morphology file.

+
+
+

TrakEM2#

+

TrakEM2 logo

+

TrakEM2 is an ImageJ plugin for morphological data mining, three-dimensional modelling and image stitching, registration, editing and annotation. As of v0.8n, a menu item “Export - NeuroML…” gives an option to export to MorphML (the anatomy of the arbors only) or NeuroML (the whole network with anatomy and synapses), for the selected trees or all trees.

+
+
+

Neuronvisio#

+

Neuronvisio logo

+

Neuronvisio is a Graphical User Interface for NEURON simulator environment with 3D capabilities. Neuronvisio makes easy to select and investigate sections’ properties, it offers easy integration with matplotlib for the plotting the results. It can save the geometry using NeuroML and the simulation results in a customised and extensible HDF5 format; the results can then be reload in the software and analysed at a later stage, without re-running the simulation.

+
+
+

CATMAID#

+

CATMAID logo

+

CATMAID is the Collaborative Annotation Toolkit for Massive Amounts of Image Data, and is a widely used tool for online reconstruction and annotation of connectomics data. Initial support for export of reconstructed neurons in NeuroML format has been added.

+
+
+

Myokit#

+

Myokit logo

+

Myokit (the Maastricht Myocyte Toolkit) is a Python-based software package created by Michael Clerx to simplify the use of numerical models in the analysis of cardiac myocytes. Initial support for importing ChannelML has been added.

+
+
+

Geppetto#

+

Geppetto logo

+

Geppetto is a web-based multi-algorithm, multi-scale simulation platform designed to support the simulation of complex biological systems and their surrounding environment. It is open source and is being developed as part of the OpenWorm project to create an in-silico model of the nematode C. elegans. It has had inbuilt support for NeuroML 2/LEMS from the start, and is suitable for many other types of neuronal models.

+
+
+
+

Other/legacy tools#

+
+

Older applications

+

Note: many of the applications listed below are no longer in active development or links no longer work.

+
+
+

PSICS#

+

The latest version of neuroConstruct can be used to generate executable scripts for PSICS based on NeuroML components.

+
+
+

Whole Brain Catalogue#

+

The Whole Brain Catalog was a graphical interface that allowed multiscale neuroscience data to be visualised relative to a 3D brain atlas.

+
+
+

PCSIM#

+

PCSIM is a tool in C++ for simulating large scale networks of cells and synapses.

+
+
+

Neuromantic#

+

Neuromantic is a freeware tool for neuronal reconstruction (similar in some ways to part of Neurolucida’s functionality). +Neuromantic mainly uses SWC/Cvapp format, but the latest version can import and export MorphML.

+
+
+

Neurospaces/ GENESIS 3#

+

The Neurospaces/ GENESIS 3 project is developing a modular reimplementation of the core of GENESIS 2 along with a number of other components for computational neuroscience as part of the GENESIS 3 initiative. +Neurospaces/GENESIS 3 currently supports reading of passive models in NeuroML format (morphology + passive parameters).

+
+
+

SplitNeuron#

+

SplitNeuron is a library written in C for data structures and functions extending SQLite to simulate large-scale networks of Izhikevich Simple Model compartments. +SplitNeuron answers a fundamental issue in large-scale simulation, data transfer between storage and functional software: it uses database not only for data storage but also as simulation engine, moving computation to data rather than using storage systems only for data holding. +This choice offers more features with less code to write and a unique way of accessing data for further analysis. +Features under development include direct import and cell/network creation from NeuroML.

+
+
+

NeurAnim#

+

NeurAnim is a research aid for computational neuroscience. +It is used to visualise and animate neural network simulations in 3D, and to render movies of these animations for use in presentations. +Networks stored in the instance based representation of NetworkML can be loaded and visualised.

+
+
+

CNrun#

+

CNrun is a neuronal network model simulator, similar in purpose to NEURON except that individual neurons are not compartmentalised. +It was built from refactored code written by Thomas Nowotny. +It reads in network topology description from a NeuroML file, where the cell_type attribute determines the unit class, one of the in-built neuron types of CNrun (e.g. Hodgkin Huxley cell by Traub and Miles (1991), Poisson oscillator, van der Pol oscillator).

+
+
+

NeuGen#

+

NeuGen is an application in Java which is able to generate networks of synaptically connected morphologically detailed neurons, as in a cortical column. +NeuGen generates sets of neurons of the different morphological classes of the cortex, e.g. pyramidal cells and stellate neurons, and connects these networks in 3D. +The latest version of NeuGen can export the generated networks to NeuroML. +Some manual editing of the generated files is required to make them valid. +The developers have been informed of the required updates which will be incorporated soon.

+
+
+

morphforge#

+

morphforge is a high level, simulator independent, Python library for building simulations of small populations of multi-compartmental neurons. +It was built as part of the PhD thesis of Mike Hull (Uni. +Edinburgh): Investigating the role of electrical coupling in small populations of interneurons in Xenopus laevis tadpoles. +Loading of morphologies in MorphML format is supported, and loading of channel descriptions from ChannelML is in progress. +Future development of morphforge will be closely aligned with the development of the multicompartmental modelling API in Python (libNeuroML).

+
+
+

NeuroTranslate#

+

NeuroTranslate is a tool that translates input files between two different languages, the NCS (Neo-Cortical Simulator) input language and NeuroML format. +It provides a user-friendly interface, which can be used to both create and edit simulations.

+
+
+

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. +Loading of morphologies in MorphML and NeuroML formats is supported.

+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/Approaches.html b/Userdocs/Software/Tools/Approaches.html new file mode 100644 index 00000000..8933d32b --- /dev/null +++ b/Userdocs/Software/Tools/Approaches.html @@ -0,0 +1,719 @@ + + + + + + + + + + + Approaches to adding NeuroML support — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Approaches to adding NeuroML support#

+

There are a number of ways that a neuronal simulator can add “support for NeuroML”, depending on how deeply it embeds/supports the elements of the language.

+
+

Commonly used approaches#

+
+

1) Native support for NeuroML elements#

+

A simulator may have an equivalent internal representation of the core concepts from NeuroML2/LEMS, and so be able to natively read/write these formats.

+

This is the approach taken in jNeuroML and EDEN.

+
+
+

2) Native ability to import NeuroML elements#

+

Another approach is for simulators to natively support importing (a subset of) NeuroML models, whereby the NeuroML components are converted to the equivalent entities in the simulator’s internal representation of the model.

+

This is the approach taken in MOOSE, Arbor and NetPyNE.

+
+
+

3) Native ability to export NeuroML elements#

+

Some simulators allow models to be created with their preferred native model description format, and then exported in valid NeuroML.

+

This is the approach taken in NEURON and NetPyNE. It is also possible to export PyNN models to NeuroML equivalents.

+
+
+

4) 3rd party mapping to simulator’s own format#

+

This is the approach taken in NEURON via jNeuroML.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/Arbor.html b/Userdocs/Software/Tools/Arbor.html new file mode 100644 index 00000000..c4ae4acb --- /dev/null +++ b/Userdocs/Software/Tools/Arbor.html @@ -0,0 +1,718 @@ + + + + + + + + + + + Arbor and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Arbor and NeuroML#

+

Arbor logo

+

Arbor is a high performance multicompartmental neural simulation library. Addition of support for NeuroML2 and LEMS is under active development.

+
+

Importing NeuroML into Arbor#

+

The current approach to supporting NeuroML in Arbor involves importing NeuroML to Arbor’s internal format.

+

See here for Arbor’s own documentation on this. It involves calling the neuroml() method in arbor pointing at the NeuroML file containing the cell you wish to load:

+
nml = arbor.neuroml('mymorphology.cell.nml')
+
+
+

See here for a worked example of this, importing a multicompartmental cell with only a passive membrane conductance.

+
+

Support for channels/synapses in LEMS#

+

There is work under way to allow reading of the dynamics of ion channels and synapses which are specified in LEMS into Arbor.

+

See thorstenhater/nmlcc for more details.

+
+
+
+

Network models in Arbor with NeuroMLlite#

+

There is preliminary support for building network specified in NeuroMLlite format directly in Arbor. See here for an example.

+
+
+

Examples#

+

Example code for interactions between NeuroML models and Arbor can be found in the Arbor Showcase repository.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/Brian.html b/Userdocs/Software/Tools/Brian.html new file mode 100644 index 00000000..b30cba63 --- /dev/null +++ b/Userdocs/Software/Tools/Brian.html @@ -0,0 +1,710 @@ + + + + + + + + + + + Brian and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Brian and NeuroML

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Brian and NeuroML#

+

Brian logo

+

Brian is an easy to use, Python based simulator of spiking networks.

+
+

Converting NeuroML model to Brian#

+

jNeuroML or pyNeuroML can be used to convert NeuroML2/LEMS models to Brian version 2. This involves pointing at a LEMS Simulation file describing what to simulate, and using the -brian2 option:

+
# Using jnml
+jnml <LEMS simulation file> -brian2
+
+# Using pynml
+pynml <LEMS simulation file> -brian2
+
+
+

This command generates a Python script (a file ending in _brian2.py) which can be run in Python and will simulate the model and plot/save the results, as outlined in the LEMS Simulation file.

+

Notes:

+
    +
  • Only single compartment cells can be converted to Brian format so far. While there is support in Brian for multicompartmental cell simulation, this is not yet covered in the jNeuroML based export.

  • +
  • There has been support for converting NeuroML models to Brian v1 (using -brian), but since this version of Brian is deprecated, and only supports Python 2, this export is no longer actively developed.

  • +
  • There is limited support for executing networks of cells in Brian, and the most likely route for adding this functionality is via NeuroMLlite.

  • +
+
+
+

Examples#

+

Example code for interactions between NeuroML models and Brian can be found here.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/EDEN.html b/Userdocs/Software/Tools/EDEN.html new file mode 100644 index 00000000..600d7af1 --- /dev/null +++ b/Userdocs/Software/Tools/EDEN.html @@ -0,0 +1,663 @@ + + + + + + + + + + + EDEN and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

EDEN and NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

EDEN and NeuroML#

+

EDEN is a recently developed simulation engine which incorporates native NeuroML 2 support from the start.

+

Initial tests of using EDEN with NeuroML models and example code can be found here.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/MOOSE.html b/Userdocs/Software/Tools/MOOSE.html new file mode 100644 index 00000000..5a0c2456 --- /dev/null +++ b/Userdocs/Software/Tools/MOOSE.html @@ -0,0 +1,697 @@ + + + + + + + + + + + MOOSE and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

MOOSE and NeuroML

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

MOOSE and NeuroML#

+

MOOSE is the Multiscale Object-Oriented Simulation Environment. It is the base and numerical core for large, detailed multi-scale simulations that span computational neuroscience and systems biology. It is based on a complete reimplementation of the GENESIS 2 core.

+

Some tests of using MOOSE with NeuroML models and example code can be found in the MOOSE Showcase repository.

+
+

Simulating NeuroML models in MOOSE#

+

You can export NeuroML models to the MOOSE simulator format using jNeuroML or pyNeuroML, pointing at a LEMS Simulation file describing what to simulate, and using the -moose option:

+
# Using jnml
+jnml <LEMS simulation file> -moose
+
+# Using pynml
+pynml <LEMS simulation file> -moose
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/N2A.html b/Userdocs/Software/Tools/N2A.html new file mode 100644 index 00000000..2c2c1708 --- /dev/null +++ b/Userdocs/Software/Tools/N2A.html @@ -0,0 +1,663 @@ + + + + + + + + + + + N2A and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

N2A and NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

N2A and NeuroML#

+

“Neurons to Algorithms” (N2A) is a language for modeling neural systems, along with a software tool for editing models and simulating them

+

See sandialabs/n2a for information on the interactions between NeuroML/LEMS and N2A.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/NEST.html b/Userdocs/Software/Tools/NEST.html new file mode 100644 index 00000000..90cc113a --- /dev/null +++ b/Userdocs/Software/Tools/NEST.html @@ -0,0 +1,670 @@ + + + + + + + + + + + NEST and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NEST and NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

NEST and NeuroML#

+

NEST logo

+

NEST is a simulator for spiking neural network models that focuses on the dynamics, size and structure of neural systems rather than on the exact morphology of individual neurons. The development of NEST is coordinated by the NEST Initiative.

+

NEST is ideal for networks of spiking neurons of any size, for example:

+
    +
  • Models of information processing e.g. in the visual or auditory cortex of mammals,

  • +
  • Models of network activity dynamics, e.g. laminar cortical networks or balanced random networks,

  • +
  • Models of learning and plasticity.

  • +
+

See OpenSourceBrain/NESTShowcase for examples of usage of NeuroML and NEST.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/NEURON.html b/Userdocs/Software/Tools/NEURON.html new file mode 100644 index 00000000..027dc822 --- /dev/null +++ b/Userdocs/Software/Tools/NEURON.html @@ -0,0 +1,734 @@ + + + + + + + + + + + NEURON and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

NEURON and NeuroML#

+

NEURON logo

+

NEURON is a widely used simulation environment and is one of the main target platforms for a standard facilitating exchange of neuronal models.

+
+

Simulating NeuroML models in NEURON#

+

jNeuroML or pyNeuroML can be used to convert NeuroML2/LEMS models to NEURON. This involves pointing at a LEMS Simulation file describing what to simulate, and using the -neuron option:

+
# Simulate the model using NEURON with python/hoc/mod files generated by jNeuroML
+jnml <LEMS simulation file> -neuron -run
+
+# Simulate the model using NEURON with python/hoc/mod files generated by pyNeuroML
+pynml <LEMS simulation file> -neuron -run
+
+
+

These commands generate a PyNeuron script and run it (a file ending in _nrn.py). +So you must have NEURON installed on your system, with its Python bindings (PyNeuron). +Skipping the -run flag will generate the Python script but will not run it: you can run it manually later. +Adding -nogui will suppress the NEURON graphical elements/menu opening and just run the model in NEURON in the background

+

You can also run LEMS simulations using the NEURON simulator using the pyNeuroML API:

+
from pyneuroml.pynml import run_lems_with_jneuroml_neuron
+
+...
+
+run_lems_with_jneuroml_neuron(lems_file_name)
+
+
+
+
+

Setting the NEURON_HOME environment variable#

+

Since it is possible to install multiple versions of NEURON in different places, the NeuroML tools need to be told where the NEURON tools are. +To do this, they look at the NEURON_HOME environment variable. +This needs to hold the path to where the binary (bin) folder holding the NEURON tools such as nrniv are located. +On Linux like systems, one can use which to find these tools and set the variable:

+
$ which nrniv
+~/.local/share/virtualenvs/neuroml-311-dev/bin/nrniv
+
+$ export NEURON_HOME="~/.local/share/virtualenvs/neuroml-311-dev/"
+
+
+

One can combine these commands together also:

+
$ export NEURON_HOME="$(dirname $(dirname $(which nrniv)))"
+
+
+
+
+

Using neuroConstruct#

+

NEURON simulations can also be generated from NeuroML model components by neuroConstruct, but most of this functionality is related to NeuroML v1.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/NetPyNE.html b/Userdocs/Software/Tools/NetPyNE.html new file mode 100644 index 00000000..e9f0d506 --- /dev/null +++ b/Userdocs/Software/Tools/NetPyNE.html @@ -0,0 +1,708 @@ + + + + + + + + + + + NetPyNE and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

NetPyNE and NeuroML

+ +
+ +
+
+ + + + +
+ +
+

NetPyNE and NeuroML#

+

NetPyNE logo

+

NetPyNE is a Python package to facilitate the development, simulation, parallelization, analysis, and optimization of biological neuronal networks using the NEURON simulator. NetPyNE can import from and export to NeuroML. NetPyNE also provides a web based Graphical User Interface.

+
+

Importing NeuroML into NetPyNE#

+

An example of how to import a network in NeuroML into NetPyNE can be found here.

+
+
+

Exporting NeuroML from NetPyNE#

+

An example of how to export a network built using NetPyNE to NeuroML can be found here.

+
+
+

Running NetPyNE on OSBv2#

+

Building and running NetPyNE models will be a core feature of Open Source Brain v2.0. See here for more details.

+
+
+

NeuroMLlite#

+

NetPyNE is also a key target for cross simulator network creation using NeuroMLlite. There are ongoing plans for greater alignment between formats used for network specification in NetPyNE and NeuroMLlite.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/Tools/PyNN.html b/Userdocs/Software/Tools/PyNN.html new file mode 100644 index 00000000..f4be2956 --- /dev/null +++ b/Userdocs/Software/Tools/PyNN.html @@ -0,0 +1,667 @@ + + + + + + + + + + + PyNN and NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

PyNN and NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

PyNN and NeuroML#

+

PyNN logo

+

PyNN is a Python package for simulator independent specification of neuronal network models. Model code can be developed using the PyNN API and then run using NEURON, NEST or Brian. The developed model also can be stored as a NeuroML document.

+

The latest version of neuroConstruct can be used to generate executable scripts for PyNN based simulators based on NeuroML components, although the majority of multicompartmental conductance based models which are available in neuroConstruct are outside the current scope of the PyNN API.

+

See OpenSourceBrain/PyNNShowcase for examples of usage of NeuroML and PyNN.

+

More info on the latest support for running NeuroML models in PyNN and vice versa can be found here.

+

PyNN is also a key target for cross simulator network creation using NeuroMLlite.

+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/jLEMS.html b/Userdocs/Software/jLEMS.html new file mode 100644 index 00000000..d7da9aa0 --- /dev/null +++ b/Userdocs/Software/jLEMS.html @@ -0,0 +1,717 @@ + + + + + + + + + + + jLEMS — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

jLEMS

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

jLEMS#

+

jLEMS is an interpreter for the Low Entropy Model Specification language written in Java.

+ +
+

Quick start#

+

Since jLEMS is included in jNeuroML, it does need not to be installed it separately. +Please follow the instructions on installing jNeuroML provided here.

+

Please see the development section below for information on building the jLEMS interpreter from source.

+
+
+

Documentation#

+

Detailed documentation on LEMS is maintained here. +For more information on LEMS, please also see Cannon et al. ([CGC+14])

+
+
+

Getting help#

+

For any questions regarding jLEMS, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

jLEMS is developed on GitHub at LEMS/jLEMS under the MIT license. +The repository contains the complete source code along with instructions on building/installing jLEMS.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/jNeuroML.html b/Userdocs/Software/jNeuroML.html new file mode 100644 index 00000000..5fa7a5b6 --- /dev/null +++ b/Userdocs/Software/jNeuroML.html @@ -0,0 +1,818 @@ + + + + + + + + + + + jNeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

jNeuroML#

+

jNeuroML is a Free/Open Source Java tool for working with LEMS and NeuroML 2. +It includes the jnml command line application, and can also be used as a Java library.

+

With jNeuroML you can:

+
    +
  • Validate NeuroML v1.8.1 and v2.x files

  • +
  • Simulate NeuroML 2 models

  • +
  • Export NeuroML 2 and LEMS files to many formats such as Neuron, Brian, Matlab, etc.

  • +
  • Import other languages into LEMS (e.g. SBML)

  • +
  • Visualise NeuroML models and simulations

  • +
+ +
+

Quick start#

+
+

Install the Java Runtime Environment#

+

Since jNeuroML is written in Java, you will need a Java Runtime Environment (JRE) installed on your system. +On most Linux systems Free/Open source OpenJDK runtime environment is already pre-installed. +You can also install Oracle’s proprietary Java platform from their download page if you prefer. +Please refer to your operating system’s documentation to install a JRE.

+
+
+

Installation using pre-compiled JAR#

+

jNeuroML is provided as a pre-compiled ready-to-use Java JAR file that can be used on any computer that has Java installed. +Please download it from the GitHub release page and unzip (extract) it in a preferred folder on your computer:

+
cd <folder where you downloaded the jNeuroML zip file>
+unzip jNeuroML.zip
+
+
+

This will extract the zip file to a new folder which will contain the pre-compiled JAR file and runner scripts:

+
ls jNeuroMLJar/
+jNeuroML-0.10.2-jar-with-dependencies.jar  jnml  jnml.bat  README
+
+
+ +
+
+

Installation on Fedora Linux#

+

On Fedora Linux systems, the NeuroFedora community provides jNeuroML as a package in their extras repository and can be installed using the following commands:

+
sudo dnf copr enable @neurofedora/neurofedora-extra
+sudo dnf install jneuroml
+
+
+
+
+
+

Documentation#

+

Information on usage of the jnml command line application can be found with the -h option:

+
jnml -h
+
+ jNeuroML v0.10.1
+Usage:
+
+    jnml LEMSFile.xml
+           Load LEMSFile.xml using jLEMS, parse it and validate it as LEMS, and execute the model it contains
+
+    jnml LEMSFile.xml -nogui
+           As above, parse and execute the model and save results, but don't show GUI
+
+    ...
+
+
+
+

API documentation#

+

The jNeuroML API is self documented. +Please refer to the various packages to learn their usage:

+ +
+
+
+

Getting help#

+

For any questions regarding jNeuroML, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

jNeuroML is developed on GitHub at NeuroML/jNeuroML under the LPGL-3.0 license. +The repository contains the complete source code along with instructions on building/installing jNeuroML. +Please follow the instructions there to build jNeuroML from source.

+
+

Nightly (pre-release) jar builds:#

+
+

Warning

+

Please note that these JARs are considered experimental and should only be used for testing purposes.

+
+

In case you want to use a development (un-released) version of jNeuroML, you can download a development build following the steps below. +You will need to have the Subversion tool installed on your system.

+
svn checkout svn://svn.code.sf.net/p/neuroml/code/jNeuroMLJar
+cd jNeuroMLJar
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/libNeuroML.html b/Userdocs/Software/libNeuroML.html new file mode 100644 index 00000000..270ea86e --- /dev/null +++ b/Userdocs/Software/libNeuroML.html @@ -0,0 +1,785 @@ + + + + + + + + + + + libNeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

libNeuroML#

+

libNeuroML is a Python package for working with models specified in NeuroML version 2. +It provides a native Python object model corresponding to the NeuroML schema. +This allows users to build their NeuroML models natively in Python without having to work directly with the underlying XML representation. +Additionally, libNeuroML includes functions for the conversion of the Python representation of the NeuroML model to and from the XML representation.

+ + +
+

Quick start#

+
+

Install Python#

+

Python is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official installation instructions to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is here.

+
+
+

Install libNeuroML with pip#

+ +

The easiest way to install the latest version of libNeuroML is using the default Python package manager, pip:

+
pip install libNeuroML
+
+
+
+
+

Installation on Fedora Linux#

+

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
+
+
+
+
+
+

Documentation#

+

Detailed API documentation for libNeuroML can be found here. +For more information on libNeuroML, please see Vella et al. ([VCC+14]) and Cannon et al. ([CGC+14]).

+

The core classes in NeuroML are Python representations of the Component Types defined in the NeuroML standard. +These can be used to build NeuroML models in Python, and these models can then be exported to the standard XML NeuroML representation. +These core classes also contain some utility functions to make it easier for users to carry out common tasks.

+
+Examples of mapping between Component names in the NeuroML schema and their corresponding libNeuroML Python classes. +
+

Fig. 64 Examples of mapping between Component names in the NeuroML schema and their corresponding libNeuroML Python classes.#

+
+
+

Each NeuroML Component Type is represented here as a Python class. +Due to implementation limitations, whereas NeuroML Component Types use lower camel case naming, the Python classes here use upper camel case naming. +So, for example, the adExIaFCell Component Type in the NeuroML schema becomes the AdExIaFCell class here, and expTwoSynapse becomes the ExpTwoSynapse class.

+

The child and children elements that NeuroML Component Types can have are represented in the Python classes as variables. +The variable names, to distinguish them from class names, use snake case. +So for example, the cell NeuroML Component Type has a corresponding Cell Python class here. +The biophysicalProperties child Component Type in cell is represented as the biophysical_properties list variable in the Cell Python class. +The class signatures list all the child/children elements and text fields that the corresponding Component Type possesses. +To again use the Cell class as an example, the construction signature is this:

+
class neuroml.nml.nml.Cell(neuro_lex_id=None, id=None, metaid=None, notes=None, properties=None, annotation=None, morphology_attr=None, biophysical_properties_attr=None, morphology=None, biophysical_properties=None, extensiontype_=None, **kwargs_)
+
+
+

As can be seen here, it includes both the biophysical_properties and morphology child elements as variables.

+

Please see the examples in the NeuroML documentation to see usage examples of libNeuroML. +Please also note that this module is also included in the top level of the neuroml package, so you can use these classes by importing neuroml:

+
from neuroml import AdExIaFCell
+
+
+
+
+

Getting help#

+

For any questions regarding libNeuroML, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

libNeuroML is developed on GitHub at NeuralEnsemble/libNeuroML under the BSD 3 clause license. +The repository contains the complete source code along with instructions on building/installing libNeuroML. +Please follow the instructions there to build libNeuroML from source.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/pyLEMS.html b/Userdocs/Software/pyLEMS.html new file mode 100644 index 00000000..a617bef7 --- /dev/null +++ b/Userdocs/Software/pyLEMS.html @@ -0,0 +1,823 @@ + + + + + + + + + + + pyLEMS — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

pyLEMS#

+

pyLEMS is a Python package which provides an API, as well as a simulator for the LEMS language. +It can also be used to run NeuroML2 models.

+ + +
+

Quick start#

+
+

Install Python#

+

Python is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official installation instructions to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is here.

+
+
+

Install pyLEMS with pip#

+ +

The easiest way to install the latest version of pyLEMS is using the default Python package manager, pip:

+
pip install pyLEMS
+
+
+
+
+

Installation on Fedora Linux#

+

On Fedora Linux systems, the NeuroFedora community provides pyLEMS in the standard Fedora repos and can be installed using the following commands:

+
sudo dnf install python3-pyLEMS
+
+
+
+
+
+

Documentation#

+

Detailed API documentation for PyLEMS can be found here. +pyLEMS provides the pylems command line utility that can be used to simulate LEMS files. +pylems is self documented, and you can learn about its usage using the -h flag:

+
pylems -h
+usage: pylems [-h] [-I <Include directory>] [-nogui] [-dlems] <LEMS file>
+
+positional arguments:
+  <LEMS file>           LEMS file to be simulated
+
+optional arguments:
+  -h, --help            show this help message and exit
+  -I <Include directory>
+                        Directory to be searched for included files
+  -nogui                If this is specified, just parse & simulate the model, but don't show any plots
+  -dlems                If this is specified, export the LEMS file as dLEMS (distilled LEMS in JSON format, see https://github.com/borismarin/som-codegen)
+
+
+

To simulate a LEMS file:

+
pylems lemsexample.xml
+
+
+

Please note that if you are simulating a NeuroML file you will have to also specify the location of the NeuroML 2 LEMS definitions with the -I option. +We suggest that you use pyNeuroML where this is not required:

+
pylems -I <dir of NeuroML2 install>/NeuroML2CoreTypes/  LEMS_NeuroML2_Model.xml
+
+
+

For more information on pyLEMS, please see Vella et al. ([VCC+14]) and Cannon et al. ([CGC+14]).

+
+

API documentation#

+

Detailed API documentation for pyNeuroML can be found here.

+

The pyLEMS API is also self documented. +You can use Python’s in-built documentation viewer pydoc to view the documentation for any of the package’s modules and their functions:

+
Help on package lems:
+
+NAME
+    lems
+
+DESCRIPTION
+    @author: Gautham Ganapathy
+    @organization: LEMS (http://neuroml.org/lems/, https://github.com/organizations/LEMS)
+    @contact: gautham@lisphacker.org
+
+PACKAGE CONTENTS
+    api
+    base (package)
+    dlems (package)
+    model (package)
+    parser (package)
+    run
+    sim (package)
+
+DATA
+    logger = <Logger LEMS (WARNING)>
+
+VERSION
+    0.5.2
+
+FILE
+    /usr/lib/python3.9/site-packages/lems/__init__.py
+
+
+

Most IDEs are able to show you this information as you use them in your Python scripts.

+
+
+
+

Getting help#

+

For any questions regarding pyLEMS, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

pyLEMS is developed on GitHub at LEMS/pylems under the LGPL-3.0 license. +The repository contains the complete source code along with instructions on building/installing pyLEMS. +Please follow the instructions there to build pyLEMS from source.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Software/pyNeuroML.html b/Userdocs/Software/pyNeuroML.html new file mode 100644 index 00000000..4c275521 --- /dev/null +++ b/Userdocs/Software/pyNeuroML.html @@ -0,0 +1,907 @@ + + + + + + + + + + + pyNeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

pyNeuroML#

+ + +

pyNeuroML is a Python package that allows you to work with NeuroML models using the Python programming language. +It includes all the API functions provided by libNeuroML and pyLEMS, and also wraps all the functions that jNeuroML provides, which can therefore be used from within Python itself.

+

With pyNeuroML you can:

+
    +
  • Create NeuroML models and simulations

  • +
  • Validate NeuroML v1.8.1 and v2.x files

  • +
  • Simulate NeuroML 2 models

  • +
  • Export NeuroML 2 and LEMS files to many formats such as Neuron, Brian, Matlab, etc.

  • +
  • Import other languages into LEMS (e.g. SBML)

  • +
  • Visualise NeuroML models and simulations

  • +
+
+jNeuroML and pyNeuroML +
+

Fig. 63 Relationship between jLEMS, jNeuroML, the NeuroML 2 LEMS definitions, libNeuroML, pyLEMS and pyNeuroML.#

+
+
+
+

Quick start#

+
+

Install Python and the Java Runtime Environment#

+

Python is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official installation instructions to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is here.

+

Since pyNeuroML wraps around jNeuroML which is written in Java, you will need a Java Runtime Environment (JRE) installed on your system. +On most Linux systems Free/Open source OpenJDK runtime environment is already pre-installed. +You can also install Oracle’s proprietary Java platform from their download page if you prefer. +Please refer to your operating system’s documentation to install a JRE.

+
+
+

Install pyNeuroML with pip#

+ +

The easiest way to install the latest version of pyNeuroML is using the default Python package manager, pip:

+
pip install pyneuroml
+
+
+

By default, this will only install the minimal set of packages required to use pyNeuroML. +To use pyNeuroML with specific supporting tools, please install them as required:

+
pip install pyneuroml[neuron]       # for NEURON simulation backend
+pip install pyneuroml[brian]        # for Brian2 simulation backend
+pip install pyneuroml[netpyne]      # for NetPyNE simulation backend
+pip install pyneuroml[povray]       # for povray functions
+pip install pyneuroml[hdf5]         # for HDF5 support
+pip install pyneuroml[analysis]     # for analysis functions
+pip install pyneuroml[tune]         # for tuning/fitting functions
+pip install pyneuroml[vispy]        # for 3D interactive morphology plotting using vispy
+pip install pyneuroml[plotly]       # for interactive plotting with plotly
+pip install pyneuroml[nsg]          # pulls in pynsgr to use NSG
+pip install pyneuroml[combine]      # includes libsbml, libsedml
+pip install pyneuroml[tellurium]    # for Tellurium simulation backend
+pip install pyneuroml[all]          # installs all of the above
+pip install pyneuroml[dev]          # installs the above and other test related packages
+pip install pyneuroml[doc]          # for building documentation
+
+
+

Please note that for compiling NEURON mod files, you also need a C compiler and the make utility installed on your computer. +Additionally, to run parallel simulations the MPI libraries are also needed. +Please see the NEURON installation documentation for more information on installing NEURON on your computer.

+

For more information on individual simulation backends, please refer to their respective documentations.

+
+
+

Installation on Fedora Linux#

+

On Fedora Linux systems, the NeuroFedora community provides pyNeuroML as a package in their extras repository and can be installed using the following commands:

+
sudo dnf copr enable @neurofedora/neurofedora-extra
+sudo dnf install python3-pyneuroml
+
+
+

Optional packages can also be installed using the default package manager:

+
sudo dnf install python3-brian2 python3-neuron neuron-devel python3-netpyne
+
+
+

MPI builds of these tools are also available in the NeuroFedora repositories. +Please see the project documentation on installing and using them.

+
+
+
+

Documentation#

+

pyNeuroML provides a set of command line utilities along with an API to use from within Python scripts:

+ +
    +
  • pynml

  • +
  • pynml-channelanalysis

  • +
  • pynml-modchananalysis

  • +
  • pynml-plotspikes

  • +
  • pynml-povray

  • +
  • pynml-sonata

  • +
  • pynml-summary

  • +
  • pynml-tune

  • +
+

These utilities are self-documented. +So, to learn how these utilities are to be used, run them with the -h flag. +For example:

+
pynml -h
+usage: pynml [-h|--help] [<shared options>] <one of the mutually-exclusive options>
+
+pyNeuroML v0.5.9: Python utilities for NeuroML2
+    libNeuroML v0.2.54
+    jNeuroML v0.10.2
+
+optional arguments:
+  -h, --help            show this help message and exit
+
+Shared options:
+  These options can be added to any of the mutually-exclusive options
+
+  -verbose              Verbose output
+  -java_max_memory MAX  Java memory for jNeuroML, e.g. 400M, 2G (used in
+                        -Xmx argument to java)
+  -nogui                Suppress GUI,
+                        i.e. show no plots, just save results
+  <LEMS/NeuroML 2 file>
+                        LEMS/NeuroML 2 file to process
+
+...
+
+
+
+

API documentation#

+

Detailed API documentation for pyNeuroML can be found here.

+

The pyNeuroML API is also self documented. +You can use Python’s in-built documentation viewer pydoc to view the documentation for any of the package’s modules and their functions:

+
pydoc pyneuroml
+Help on package pyneuroml:
+
+NAME
+    pyneuroml
+
+PACKAGE CONTENTS
+    analysis (package)
+    lems (package)
+    neuron (package)
+    plot (package)
+    povray (package)
+    pynml
+    swc (package)
+    tune (package)
+
+DATA
+    JNEUROML_VERSION = '0.10.2'
+
+VERSION
+    0.5.9
+
+FILE
+    /usr/lib/python3.9/site-packages/pyneuroml/__init__.py
+
+
+
pydoc pyneuroml.analysis
+
+Help on package pyneuroml.analysis in pyneuroml:
+
+NAME
+    pyneuroml.analysis
+
+PACKAGE CONTENTS
+    ChannelDensityPlot
+    ChannelHelper
+    NML2ChannelAnalysis
+
+FUNCTIONS
+    analyse_spiketime_vs_dt(nml2_file, target, duration, simulator, cell_v_path, dts, verbose=False, spike_threshold_mV=0, show_plot_already=True, save_figure_to=None, num_of_last_spikes=None)
+
+    generate_current_vs_frequency_curve(nml2_file, cell_id, start_amp_nA=-0.1, end_amp_nA=0.1, step_nA=0.01, custom_amps_nA=[], analysis_duration=1000, analysis_delay=0, pre_zero_pulse=0, post_zero_pulse=0, dt=0.05, temperature='32degC', spike_threshold_mV=0.0, plot_voltage_traces=False, plot_if=True, plot_iv=False, xlim_if=None, ylim_if=None, xlim_iv=None, ylim_iv=None, label_xaxis=True, label_yaxis=True, show_volts_label=True, grid=True, font_size=12, if_iv_color='k', linewidth=1, bottom_left_spines_only=False, show_plot_already=True, save_voltage_traces_to=None, save_if_figure_to=None, save_iv_figure_to=None, save_if_data_to=None, save_iv_data_to=None, simulator='jNeuroML', num_processors=1, include_included=True, title_above_plot=False, return_axes=False, verbose=False)
+
+FILE
+    /usr/lib/python3.9/site-packages/pyneuroml/analysis/__init__.py
+
+
+

Most IDEs are able to show you this information as you use them in your Python scripts.

+
+
+
+

Getting help#

+

For any questions regarding pyNeuroML, please open an issue on the GitHub issue tracker here. +Any bugs and feature requests can also be filed there.

+

You can also use any of the communication channels of the NeuroML community.

+
+
+

Development#

+

pyNeuroML is developed on GitHub at NeuroML/pyNeuroML under the LPGL-3.0 license. +The repository contains the complete source code along with instructions on building/installing pyNeuroML. +Please follow the instructions there to build pyNeuroML from source.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Specification.html b/Userdocs/Specification.html new file mode 100644 index 00000000..1f11ab82 --- /dev/null +++ b/Userdocs/Specification.html @@ -0,0 +1,684 @@ + + + + + + + + + + + Schema/Specification — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Schema/Specification

+ +
+
+ +
+
+
+ + + + +
+ +
+

Schema/Specification#

+
+

NeuroML v2.3 is the current stable release of the language, and is described below.

+

For an overview of the various releases of the language see: A brief history of NeuroML.

+
+

We’ve briefly seen the XML representation of NeuroML models and simulations in the Getting Started tutorials. +Here, we dive a little deeper into the underlying details of NeuroML.

+

XML itself does not define a set of standard tags: any tags may be used as long as the resultant document is well-formed. +Therefore, NeuroML defines a standard set of XML elements (the tags and attributes which specify the model and parameters, e.g. <iafCell id="iaf" leakReversal="-60mV"...>) that may be used in NeuroML documents: the NeuroML XML Schema Definition. +This is referred to as the NeuroML schema or the NeuroML specification.

+

As the wiki page says:

+
+

XSD (XML Schema Definition), a recommendation of the World Wide Web Consortium (W3C), specifies how to formally describe the elements in an Extensible Markup Language (XML) document. It can be used by programmers to verify each piece of item content in a document, to assure it adheres to the description of the element it is placed in.

+
+

This gives us an idea of the advantages of using an XML based system. +All NeuroML models must use these pre-defined tags/components—this is what we check for when we validate NeuroML models. +A valid NeuroML model is said to adhere to the NeuroML schema.

+
+

Purpose of the NeuroML specification/schema.

+

The NeuroML schema/specification defines the structure of a valid NeuroML document. The core NeuroML tools adhere to this specification and can read/write/interpret the language correctly.

+
+

In the next section, we learn more about the NeuroML 2 schema, and see how the dynamics of the NeuroML 2 entities are defined in LEMS.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/TestingNeuroMLModels.html b/Userdocs/TestingNeuroMLModels.html new file mode 100644 index 00000000..e9e85912 --- /dev/null +++ b/Userdocs/TestingNeuroMLModels.html @@ -0,0 +1,725 @@ + + + + + + + + + + + Testing/validating NeuroML Models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Testing/validating NeuroML Models#

+

Models described in NeuroML can be run across multiple simulators, and it it essential that the activity (e.g. spike times) of the models are as close as possible across all of these independently developed platforms.

+

It is also important to validate that the behaviour of a given NeuroML model reproduces some recorded aspect of the biological equivalent.

+
+

Testing behaviour of NeuroML models across simulators#

+

This type of testing addresses the question: Does a given NeuroML model produce the same results when run across multiple simulators?

+
+

OMV - Open Source Brain Model Validation framework#

+

The OSB Model Validation framework was originally developed as an automated model validation package for Open Source Brain projects, which can be used for testing model behaviour across many simulation engines both:

+
    +
  • on your local machine when developing models

  • +
  • on GitHub Actions, to ensure tests pass on every commit.

  • +
+

This framework has been used to test the 30+ NeuroML and PyNN models described in the Open Source Brain paper (Gleeson et al. 2019), and many more.

+

See OpenSourceBrain/osb-model-validation for more details.

+
+
+
+

Validating that NeuroML model reproduce biological activity#

+

This type of testing addresses the question: How well does a given NeuroML model replicate the activity as seen in real neurons/channels/networks?

+
+

SciUnit/NeuronUnit#

+

SciUnit is a Python framework for test-driven validation of scientific models, and NeuronUnit +is a package based on this for data-driven validation of neuron and ion channel models. See also SciDash for more information.

+

Interactive Jupyter notebooks for running NeuronUnit examples can be found this repository.

+

TODO: Add details on using SciUnit and NeuronUnit with NeuroML models.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/UnitsAndDimensions.html b/Userdocs/UnitsAndDimensions.html new file mode 100644 index 00000000..20e00cdd --- /dev/null +++ b/Userdocs/UnitsAndDimensions.html @@ -0,0 +1,675 @@ + + + + + + + + + + + Units and dimensions — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Units and dimensions

+ +
+
+ +
+
+
+ + + + +
+ +
+

Units and dimensions#

+

Support for dimensional quantities is a fundamental (and essential) feature of NeuroML, backed up by support for units and dimensions in LEMS.

+

The basic rules are:

+
    +
  • specify the dimensions of quantities in LEMS

  • +
  • use compatible units defined in the NeuroML schema in NeuroML models.

  • +
+

The main motivation for this is that fundamental expressions for defining a model are independent of any particular units. +For example, Ohm’s law, V = I * R relates to quantities with dimensions voltage, current and resistance, not millivolts, picoamps, ohms, etc.

+

Users can therefore use a wide range of commonly used units for each dimension defined in the standard unit and dimension definitions of NeuroML 2 without worrying about conversion factors.

+

Additionally, please keep in mind that:

+
    +
  • all quantities are saved and recorded in SI Units

  • +
  • when plotting data using NeuroML/LEMS using the Line component, users can use the scale parameter to convert quantities to other units.

  • +
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Usage.html b/Userdocs/Usage.html new file mode 100644 index 00000000..6ab97c40 --- /dev/null +++ b/Userdocs/Usage.html @@ -0,0 +1,807 @@ + + + + + + + + + + + How to use this documentation — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

How to use this documentation#

+

This documentation is generated using Jupyter books. +You can learn more about the project on their website.

+
+

Structure and navigation#

+
+

Close the left hand side bar using the burger menu on the left side of the top panel.

+

You can close the left hand side bar by clicking the burger menu on the left side of the top panel. +This increases the width of the middle section of the documentation and can be helpful on smaller screens. +Clicking the hamburger menu again will re-open it.

+
+

The documentation is divided into a few parts that can be seen in the left hand side navigation bar:

+
    +
  • User documentation: this includes documentation for anyone looking to use NeuroML

  • +
  • NeuroML events: any events related to NeuroML will be listed here

  • +
  • The NeuroML Initiative: this includes documentation on the NeuroML community

  • +
  • Developer documentation: this includes information for individuals looking to contribute to NeuroML (either the standard or the software)

  • +
  • Reference: this includes the glossary of terms and the bibliography.

  • +
+

Each part contains different chapters, which can each contain different sections. +Each page in the documentation also has its own navigation in the right hand side bar.

+
+
+

Using Jupyter notebooks included in the documentation#

+
+

Familiar with Jupyter Notebooks? Skip ahead to the next section.

+

If you are familiar with Jupyter Notebooks, you can skip ahead to the Getting started with NeuroML section.

+
+

The most important feature of Jupyter books is that it allows you to include Jupyter notebooks in the documentation. +This allows us to write documentation which includes code examples that can be modified and executed by users interactively in their browsers without having to install anything on their local machines. +For example, these are used in the Getting Started section.

+

Each Jupyter notebook in the documentation includes a rocket icon 🚀 in the top bar:

+
+Click the rocket icon in top panel of executable pages to execute them in Binder or Google Collaboratory. +
+

Fig. 1 Click the rocket icon in top panel of executable pages to execute them in Binder or Google Collaboratory.#

+
+
+

Clicking this icon will allow you to run the Jupyter Notebook:

+
+You can run the Jupyter Notebook on Binder or Google Colaboratory. +
+

Fig. 2 You can run the Jupyter Notebook on Binder or Google Colaboratory.#

+
+
+

You can choose from freely available services such as Binder and Google Colaboratory. +Both Binder and Google Colaboratory will take you to these services and load the Jupyter Notebook for you to use. +The Live code option uses Binder but allows you to run the code in the current tab itself. +However, please note that this option does not include the full Jupyter Notebook features that Binder and Google Colaboratory provide.

+
+

Run Binder and Google Colaboratory in a new tab.

+

It is suggested to right click and select “Open in new tab” so that the tab with the NeuroML documentation remains open. +In most browsers, you can also use Ctrl + click to open links in a new tab:

+
+
+Izhikevich example running in Binder. +
+

Fig. 3 Izhikevich example running in Binder#

+
+
+
+Izhikevich example running in Google Colaboratory. +
+

Fig. 4 Izhikevich example running in Google Colaboratory.#

+
+
+
+Izhikevich example running on Binder but using the Live Code option. +
+

Fig. 5 Izhikevich example running in Binder but using the Live Code option.#

+
+
+

When running the Jupyter notebooks using these services, you can make changes to the code and re-run it as required. +On Binder and Google Colaboratory, which provide the full range of Jupyter Notebook features, you can also run all the code cells at once in sequence. +Please see the documentation pages to learn more about using Binder and Google Colaboratory here and here respectively. +General information on using Jupyter Notebooks and the interface can be found in the documentation here.

+
+

Downloading Jupyter Notebooks to run locally on your machine#

+

Jupyter Notebooks can also be downloaded and run locally on your machine. +To download the notebooks, use the Download link in the top panel:

+
+Jupyter notebooks can be downloaded using the Download link in the top panel. +
+

Fig. 6 Jupyter notebooks can be downloaded using the Download link in the top panel.#

+
+
+

You will need to install the Python Jupyter Notebook packages to do so. +Please refer to the Jupyter Notebook documentation to see how you can install Jupyter Notebooks. +Additionally, you will also need to install the NeuroML software to run these notebooks. +Information on using Jupyter Notebooks and the interface can be found in the documentation here.

+
+
+
+

Downloading this documentation as PDF#

+

You can download this documentation as PDF pages for offline use.

+

To download individual pages, use the download icon in the top bar. +This will generate a PDF page of the current page for you, using your browser’s “print to file” functionality.

+

You can also download the complete book as a PDF here.

+
+
+

Reporting bugs and issues#

+

Please report any issues that you may find in the documentation so that it can be improved. +To report an issue on a particular page, you can use the “open issue” link under the GitHub icon in the top panel. +Additionally, you can also suggest edits by editing the page in a fork and opening a pull request using the “suggest and edit” link.

+
+You can report issues and suggest edits to the documentation to help us improve it using the options in the GitHub icon in the top panel. +
+

Fig. 7 You can report issues and suggest edits to the documentation to help us improve it using the options in the GitHub icon in the top panel.#

+
+
+

You can also always contact the NeuroML community using our communication channels if required.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/ValidatingNeuroMLModels.html b/Userdocs/ValidatingNeuroMLModels.html new file mode 100644 index 00000000..78073033 --- /dev/null +++ b/Userdocs/ValidatingNeuroMLModels.html @@ -0,0 +1,838 @@ + + + + + + + + + + + Validating NeuroML Models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Validating NeuroML Models

+ +
+ +
+
+ + + + +
+ +
+

Validating NeuroML Models#

+
+

Validate NeuroML 2 files before using them.

+

It is good practice to validate NeuroML 2 files to check them for correctness before using them.

+
+

Models described in NeuroML must adhere to the NeuroML specification. +This allows all NeuroML models to be checked for correctness: validation. +There are a number of ways of validating NeuroML model files.

+
+

Using the command line tools#

+

Both pynml (provided by pyNeuroML) and jnml (provided by jNeuroML) can validate individual NeuroML files:

+
Usage:
+
+# For NeuroML 2
+jnml -validate <NML file(s)>
+pynml <NML file(s)> -validate
+
+# For NeuroML 1 (deprecated)
+jnml -validatev1 <NML file>
+pynml <NML file(s)> -validatev1
+
+
+
+
+

Using the Python API#

+

The pyNeuroML Python API provides a number of methods to validate NeuroML 2 files. +The first is the aptly named validate_neuroml2 function:

+
from pyneuroml.pynml import validate_neuroml2
+
+...
+
+validate_neuroml2(nml_filename)
+
+
+

Similarly, the validate_neuroml1 function can be used to validate NeuroML v1 files.

+

If you are loading NeuroML files into your Python script, the read_neuroml2_file function also includes validation:

+
from pyneuroml.pynml import read_neuroml2_file
+
+
+....
+
+
+read_neuroml2_file(nml_filename, include_includes=True, check_validity_pre_include=True)
+
+
+

This will read (load) the provided NeuroML 2 file and all the files that are recursively included by it, and validate them all while it loads them.

+
+
+

List of validation tests#

+

These tests are made against the Schema document.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Test

Description

Check names

Check that names of all elements, attributes, parameters match those provided in the schema

Check types

Check that the types of all included elements

Check values

Check that values follow given restrictions

Check inclusion

Check that required elements are included

Check cardinality

Check the number of elements

Check hierarchy

Check that child/children elements are included in the correct parent elements

Check sequence order

Check that child/children elements are included in the correct order

+

These are additional validation tests that are run on models (defined here):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Test

Description

Check top level ids

Check that top level (root) elements have unique ids

Check Network level ids

Check that child/children of the Network element have unique ids

Check Cell Segment ids

Check that all Segments in a Cell have unique ids

Check single Segment without parent

Check that only one Segment is without parents (the soma Segment)

Check SegmentGroup ids

Check that all SegmentGroups in a Cell have unique ids

Check Member segment ids exist

Check that Segments referred to in SegmentGroup Members exist

Check SegmentGroup definition

Check that SegmentGroups being referenced are defined

Check SegmentGroup definition order

Check that SegmentGroups are defined before being referenced

Check included SegmentGroups

Check that SegmentGroups referenced by Include elements of other SegmentGroups exist

Check numberInternalDivisions

Check that SegmentGroups define numberInternalDivisions (used by simulators to discretize un-branched branches into compartments for simulation)

Check included model files

Check that model files included by other files exist

Check Population component

Check that a component id provided to a Population exists

Check ion channel exists

Check that an ion channel used to define a ChannelDensity element exists

Check concentration model species

Check that the species used in ConcentrationModel elements are defined

Check Population size

Check that the size attribute of a PopulationList matches the number of defined Instances

Check Projection component

Check that Populations used in the Projection elements exist

Check Connection Segment

Check that the Segment used in Connection elements exist

Check Connection pre/post cells

Check that the pre- and post-synaptic cells used in Connection elements exist and are correctly specified

Check Synapse

Check that the Synapse component used in a Projection element exists

Check root id

Check that the root Segment in a Cell morphology has id (0)

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/VisualisingCells.html b/Userdocs/VisualisingCells.html new file mode 100644 index 00000000..9402bd94 --- /dev/null +++ b/Userdocs/VisualisingCells.html @@ -0,0 +1,763 @@ + + + + + + + + + + + Visualising and analysing cell models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Visualising and analysing cell models#

+

The NeuroML ecosystem include a number of utilities for analysis and visualisation of cells. +Cell morphologies can either be visualised programmatically using the core tools, or using the many advanced neuroinformatics tools in the ecosystem that support NeuroML. +In addition to the resources listed below, you can also use the visualisation features of any other tools that read NeuroML. +E.g., NetPyNE and NetPyNE-UI, neuroConstruct, Arbor and others.

+
+

Visualising morphology of multi-compartmental cell models#

+

Multi-compartmental cells can be visualised using the plot_2D and plot_interactive_3D methods included in pyNeuroML. +This functionality is also exposed via the pynml-plotmorph command line tool.

+
+Morphology of example cell plotted with `plot_2D` +
+

Fig. 37 Morphology of example cell plotted with plot_2D in the X-Y plane.#

+
+
+
+
+ Morphology of example cell visualised interactively using `plot_interactive_3D` +
+
+

Visualising morphology of multi-compartmental cell models in NeuroML-db#

+

The NeuroML-DB platform shows detailed cell morphologies of all cells included in its database.

+
+Morphology of cell shown in NeuroML-DB. +
+

Fig. 38 Visualisation of morphology of an example cell on NeuroML-DB.#

+
+
+
+
+

Visualising morphology of multi-compartmental cell models in Open Source Brain#

+

The Open Source Brain platform also provides advanced visualisation capabilities that can be used to visualise the morphologies of NeuroML cells.

+
+Morphology of cell shown on Open Source Brain. +
+

Fig. 39 Interactive visualisation of morphology of an example cell on Open Source Brain.#

+
+
+
+
+
+

Analysing cell electrophysiology#

+

The core tools also include utilities to aid in the analysis of cell electrophysiology. +pyNeuroML includes the generate_current_vs_frequency_curve utility function that can be used to generate current-frequency, current-sub-threshold voltage, and to plot voltage traces generated at the soma for different current injections. +For example, we can analyse the OLM cell from our tutorial:

+
generate_current_vs_frequency_curve("source/Userdocs/NML2_examples/olm.cell.nml", "olm", simulator="jNeuroML_NEURON", plot_iv=True, plot_if=True, plot_voltage_traces=True)
+
+
+

This will generate these figures:

+
+F-I curve for OLM cell generated using `generate_current_vs_frequency_curve`. +
+

Fig. 40 F-I curve for OLM cell generated using generate_current_vs_frequency_curve.#

+
+
+
+Current vs sub-threshold voltage curve for OLM cell generated using `generate_current_vs_frequency_curve`. +
+

Fig. 41 Current vs sub-threshold voltage curve for OLM cell generated using generate_current_vs_frequency_curve.#

+
+
+
+Voltage traces for OLM cell with different injection currents generated using `generate_current_vs_frequency_curve`. +
+

Fig. 42 Voltage traces for OLM cell with different injection currents generated using generate_current_vs_frequency_curve.#

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/VisualisingChannels.html b/Userdocs/VisualisingChannels.html new file mode 100644 index 00000000..5c6c7538 --- /dev/null +++ b/Userdocs/VisualisingChannels.html @@ -0,0 +1,805 @@ + + + + + + + + + + + Visualising and analysing ion channel models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Visualising and analysing ion channel models#

+

A core part of NeuroML is the ability to specify voltage dependent (and potentially concentration dependent) membrane conductances, which are due to ion channels.

+
+

Help converting/examining channels in NeuroML#

+

Converting your own ion channel models to NeuroML is facilitated by examples (e.g. a simple HH Na+ channel) and the specification documentation (e.g. for <ionChannelHH>, <gateHHrates>, <HHExpLinearRate>, but there are also a number of software tools which can be used to view the internal properties of the ion channels, as well as their behaviour.

+
+

Converting cell models to NeuroML

+

Note: there is a full guide to Converting cell models to NeuroML and sharing them on Open Source Brain which uses some of the tools and methods below.

+
+
+

1) Use jnml -info (note not in pynml yet…)#

+

jNeuroML can be used on channel files for a quick summary of the contents.

+
> jnml NaConductance.channel.nml -info
+
+ jNeuroML v0.12.0
+
+Information on contents of NeuroML 2 file
+Ion Channel NaConductance:
+    ID: NaConductance
+    Description: HH Na Channel
+    Gates:
+        gate m:
+            instances: 3
+            forward rate: 1e3 * (v - (-0.04))/0.01 / ( 1 - exp(-(v - (-0.04)) / 0.01))
+            reverse rate: 4e3 * exp((v - (-0.065))/-0.018)
+        gate h:
+            instances: 1
+            forward rate: 70 * exp((v - (-0.065))/-0.02)
+            reverse rate: 1e3 /(1 + exp((v - (-0.035))/0.01))
+
+
+
+
+

2) Use pynml utilities in pyNeuroML#

+

pyNeuroML comes with 3 utilities which help enable examination of the properties of ion channels, both based on NeuroML and NEURON mod files.

+
pynml-channelanalysis NaConductance.channel.nml   # Analyse a NeuroML 2 channel
+pynml-plotchan cell.nml   # Plot distribution of peak channel conductances over cell morphology
+pynml-modchananalysis NaConductance               # Analyse a NEURON channel e.g. from NaConductance.mod
+
+
+
+

pynml_channelanalyse

+

pynml-channelanalysis includes a number of options for generating graphs of channel activity under different conditions (see here for details).

+
pynml-channelanalysis NaTa_t.channel.nml  -erev 55 -stepTargetVoltage 10 -clampDuration 5 -i -duration 7 -clampDelay 1
+
+
+

pynml_analyse_Na

+

pynml-plotchan will plot the distribution of peak conductances of all channels in a cell over its morphology, and also show distribution as a function of distance from the soma. +For example, the figure below shows the distribution of the Ih channel in the layer 5 pyramidal neuron model on the neuronal morphology on the left, and the value at different distances from the soma on the right.

+

pynml_analyse_plotchan

+

This functionality is also available as a Python function for use in scripts.

+
+
+

4) Load cell model on to OSBv1 & analyse the channels#

+

Open Source Brain (version 1) includes channel analysis functionalities.

+

osb_channel_analysis

+
+
+

5) Export to one of the supported simulators#

+

Exporting to Neuron say (jnml LEMS_NML2_Ex5_DetCell.xml -neuron) will produce mod files with the “flattened” equations:

+
...
+DERIVATIVE states {
+    rates()
+    m_q' = rate_m_q
+    h_q' = rate_h_q
+
+}
+
+PROCEDURE rates() {
+
+    m_forwardRate_x = (v -  m_forwardRate_midpoint ) /  m_forwardRate_scale ? evaluable
+    if (m_forwardRate_x  != 0)  {
+        m_forwardRate_r = m_forwardRate_rate  *  m_forwardRate_x  / (1 - exp(0 -  m_forwardRate_x )) ? evaluable cdv
+    } else if (m_forwardRate_x  == 0)  {
+        m_forwardRate_r = m_forwardRate_rate ? evaluable cdv
+    }
+...
+
+
+

Exporting to Brian 2 (jnml LEMS_NML2_Ex5_DetCell.xml -brian2) will also produce a large file with the explicit expressions…

+
...
+hhcell_eqs=Equations('''
+    dbioPhys1_membraneProperties_NaConductances_NaConductance_m_q/dt = ((bioPhys1_membraneProperties_NaConductances_NaConductance_m_inf - bioPhys1_membraneProperties_NaConductances_NaConductance_m_q) / bioPhys1_membraneProperties_NaConductances_NaConductance_m_tau) :  1
+    dbioPhys1_membraneProperties_NaConductances_NaConductance_h_q/dt = ((bioPhys1_membraneProperties_NaConductances_NaConductance_h_inf - bioPhys1_membraneProperties_NaConductances_NaConductance_h_q) / bioPhys1_membraneProperties_NaConductances_NaConductance_h_tau) :  1
+    dbioPhys1_membraneProperties_KConductances_KConductance_n_q/dt = ((bioPhys1_membraneProperties_KConductances_KConductance_n_inf - bioPhys1_membraneProperties_KConductances_KConductance_n_q) / bioPhys1_membraneProperties_KConductances_KConductance_n_tau) :  1
+    dv/dt = ((iChannels + iSyn) / totCap) :  volt
+    morph1_0_LEN = 1.0 * meter : meter
+...
+    bioPhys1_membraneProperties_KConductances_erev = -0.077 * volt : volt
+    bioPhys1_membraneProperties_KConductances_condDensity = 360.0 * kilogram**-1 * meter**-4 * second**3 * amp**2 : kilogram**-1 * meter**-4 * second**3 * amp**2
+    bioPhys1_membraneProperties_KConductances_KConductance_conductance = 1.0E-11 * siemens : siemens
+    bioPhys1_membraneProperties_KConductances_KConductance_n_instances = 4.0: 1
+    bioPhys1_membraneProperties_KConductances_KConductance_n_forwardRate_rate = 100.0 * second**-1 : second**-1
+    bioPhys1_membraneProperties_KConductances_KConductance_n_forwardRate_midpoint = -0.055 * volt : volt
+    bioPhys1_membraneProperties_KConductances_KConductance_n_forwardRate_scale = 0.01 * volt : volt
+    bioPhys1_membraneProperties_KConductances_KConductance_n_reverseRate_rate = 125.0 * second**-1 : second**-1
+    bioPhys1_membraneProperties_KConductances_KConductance_n_reverseRate_midpoint = -0.065 * volt : volt
+    bioPhys1_membraneProperties_KConductances_KConductance_n_reverseRate_scale = -0.08 * volt : volt
+
+
+

Both very verbose, but it’s possible to see at least what explicit expressions are being used for the channels…

+
+
+

6) Use NeuroML-DB#

+

NeuroML-DB also provides analysis features for Ion channels.

+

neuromldb-channel-analysis

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/VisualisingNeuroMLModels.html b/Userdocs/VisualisingNeuroMLModels.html new file mode 100644 index 00000000..eb5127ff --- /dev/null +++ b/Userdocs/VisualisingNeuroMLModels.html @@ -0,0 +1,1001 @@ + + + + + + + + + + + Visualising NeuroML Models — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Visualising NeuroML Models#

+

A number of the NeuroML software tools can be used to easily visualise models described in NeuroML.

+
+

Get a quick summary of your model#

+
+

Using command line tools#

+

You can get a quick summary of your NeuroML model using the pynml-summary command line tool that is provided by pyNeuroML:

+
Usage:
+pynml-summary <NeuroML file>
+
+
+

For example, to get a quick summary of the Primary Auditory Cortex model by Dave Beeman (see it here on Open Source Brain), one can run:

+
pynml-summary MediumNet.net.nml
+
+*******************************************************
+* NeuroMLDocument: network_ACnet2
+*
+*  PulseGenerator: ['BackgroundRandomIClamps']
+*
+*  Network: network_ACnet2 (temperature: 6.3 degC)
+*
+*   60 cells in 2 populations
+*     Population: baskets_12 with 12 components of type bask
+*       Locations: [(372.5585, 75.3425, 459.2106), ...]
+*       Properties: color=0.0 0.19921875 0.59765625;
+*     Population: pyramidals_48 with 48 components of type pyr_4_sym
+*       Locations: [(64.2564, 0.6838, 94.8305), ...]
+*       Properties: color=0.796875 0.0 0.0;
+*
+*   984 connections in 4 projections
+*     Projection: SmallNet_bask_bask from baskets_12 to baskets_12, synapse: GABA_syn_inh
+*       60 connections: [(Connection 0: 3:0(0.41661) -> 0:0(0.68577)), ...]
+*     Projection: SmallNet_bask_pyr from baskets_12 to pyramidals_48, synapse: GABA_syn
+*       336 connections: [(Connection 0: 10:0(0.05824) -> 0:6(0.02628)), ...]
+*     Projection: SmallNet_pyr_bask from pyramidals_48 to baskets_12, synapse: AMPA_syn_inh
+*       252 connections: [(Connection 0: 1:0(0.89734) -> 0:1(0.09495)), ...]
+*     Projection: SmallNet_pyr_pyr from pyramidals_48 to pyramidals_48, synapse: AMPA_syn
+*       336 connections: [(Connection 0: 14:0(0.52814) -> 0:3(0.10797)), ...]
+*
+*   14 inputs in 1 input lists
+*     Input list: BackgroundRandomIClamps to pyramidals_48, component BackgroundRandomIClamps
+*       14 inputs: [(Input 0: 37:0(0.500000)), ...]
+*
+*******************************************************
+
+
+
+
+

Using pyNeuroML#

+

You can also get a summary of your model from within your pyNeuroML script itself using the summary function:

+
import pyneuroml.pynml
+
+...
+
+
+pyneuroml.pynml.summary(nml2_doc)
+
+
+
+
+
+

View the 3D structure of your model#

+
+

Using command line tools#

+

You can generate an image of the 3D structure of the NeuroML model using the pynml command provided by pyNeuroML, or using the jnml command provided by jNeuroML:

+
Usage:
+pynml -png/-svg <NeuroML file>
+jnml -png/-svg <NeuroML file>
+
+
+

For example, to generate a PNG image of the Auditory Cortex model used above, we can use (use -svg to generate a vectorised SVG image instead of a PNG):

+
pynml -png MediumNet.net.nml
+
+
+

This generates the following image showing different views of the network :

+
+Graphical view of the Auditory Cortex model generated with pynml +
+

Fig. 31 Graphical view of the Auditory Cortex model generated with pynml#

+
+
+

An visualiser is also included in pyneuroml as pynml-plotmorph which includes both 2D and 3D views:

+
Usage:
+pynml-plotmorph <NeuroML file>
+pynml-plotmorph -i <NeuroML file>
+
+
+
+A network visualised with `pynml-plotmorph` +
+

Fig. 32 Matplotlib based 2D visualisation of a network with pynml-plotmorph.#

+
+
+
+
+ Example network visualised interactively using `pynml-plotmorph`

+
+

You can also generate graphical representations that can be viewed with the Persistence of Vision Raytracer (POV-Ray) tool using the pynml-povray tool. +For example:

+
pynml-povray MediumNet.net.nml -scalez 8
+povray Antialias=On Antialias_Depth=10 Antialias_Threshold=0.1 Output_to_File=y Output_File_Type=N Output_File_Name=Acnet-medium.povray +W1200 +H900 MediumNet.net.nml.pov
+
+
+

generates this image:

+
+Graphical view of the Auditory Cortex model generated with pynml-povray and POV-Ray +
+

Fig. 33 Graphical view of the Auditory Cortex model generated with pynml-povray and POV-Ray#

+
+
+

You can also use POV-Ray interactively. +Please refer to the official website for more information on installing and using POV-Ray. +On Fedora Linux systems, you can install it from the Fedora repositories using dnf:

+
sudo dnf install povray
+
+
+
+
+

Using pyNeuroML#

+

These functions are also exposed as Python functions in pyNeuroML, so that you can use them directly in Python scripts:

+
import pyneuroml.pynml
+
+pyneuroml.pynml.nml2_to_png(nml2_doc)
+pyneuroml.pynml.nml2_to_svg(nml2_doc)
+
+
+from pyneuroml.plot.PlotMorphology import plot_2D
+from pyneuroml.plot.PlotMorphologyVispy import plot_interactive_3D
+
+plot_2D(nml2_doc)
+plot_interactive_3D(nml2_doc)
+
+
+
+

Open Source Brain uses NeuroML.

+

The Open Source Brain platform generates the interactive visualisations from NeuroML sources. +See the Auditory Cortex model on Open Source Brain here.

+
+
+
+
+

View the connectivity graph of your model#

+
+

Using command line tools#

+ +

You can generate an image of the 3D structure of the NeuroML model using pynml:

+
Usage:
+pynml <NeuroML file> -graph <level, engine>
+
+
+

For example, to generate a PNG image of the Auditory Cortex model used above, we can use:

+
pynml MediumNet.net.nml -graph 1d
+
+
+

This generates the following image showing different views of the network :

+
+Level 1 network graph generated by pynml +
+

Fig. 34 Level 1 network graph generated by pynml#

+
+
+

You can modify the level of detail included in the graph by using different values of levels. +For example, this command generates a level 5 graph:

+
pynml MediumNet.net.nml -graph 5d
+
+
+
+Level 5 network graph generated by pynml +
+

Fig. 35 Level 5 network graph generated by pynml#

+
+
+
+
+

Using pyNeuroML#

+

You can also generated these figures from within your pyNeuroML script itself using the generate_nmlgraph function:

+
import pyneuroml.pynml
+
+...
+
+
+pyneuroml.pynml.generate_nmlgraph(nml2_doc, level="1", engine="dot")
+
+
+
+
+
+

View the connectivity matrices of the model#

+

You can generate the connectivity matrices of projections between neuronal populations of the NeuroML model using pynml:

+
Usage:
+pynml <NeuroML file> -matrix <level>
+
+
+

For example, to generate a PNG image of the connectivity matrices in the Auditory Cortex model used above, we can use:

+
pynml MediumNet.net.nml -matrix 1
+
+
+

This generates the following images showing different views of the connectivity matrices in the network :

+
+
+
+
+Connectivity matrix generated by pynml - sum of signed weights +
+
+
+
+Connectivity matrix generated by pynml - average magnitude of conductance received by post-synaptic neurons +
+
+
+
+Connectivity matrix generated by pynml - number of connections +
+
+
+
+Connectivity matrix generated by pynml - average conductance received by post-synaptic neurons +
+
+
+
+Connectivity matrix generated by pynml - average weight per connection +
+
+
+
+
+
+

View graph of the simulation instance of the model#

+
+

Using command line tools#

+

When you have created a simulation instance of the NeuroML model using LEMS, you can also visualise this using pynml or jnml:

+
Usage:
+pynml <LEMS simulation file> -lems-graph
+jnml <LEMS simulation file> -lems-graph
+
+
+

For example, to generate the LEMS graph for the Izhikevich neuron network example, we will use:

+
jnml LEMS_example_izhikevich2007network_sim.xml -lems-graph
+
+
+

will generate:

+
+Model summary graph generated using jnml. +
+

Fig. 36 A summary graph of the model generated using jnml.#

+
+
+

Note that the -lems-graph option does not take options for levels of detail. +It shows all the details of the simulation instance, and so is better suited for simpler models rather than detailed conductance based network models. +For example, for the Auditory Cortex model, this very very detailed image is generated (please click to open: it is too large to display in the page).

+
+
+

Using pyNeuroML#

+

You can also generated these figures from within your pyNeuroML script itself using the generate_lemsgraph function:

+
import pyneuroml.pynml
+
+...
+
+pyneuroml.pynml.generate_lemsgraph(lems_file)
+
+
+
+
+
+

Viewing/analysing ion channel dynamics#

+

There is a dedicated section on visualising and analysing ion channel models.

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Walkthroughs/RayEtAl2020/Conversion.html b/Userdocs/Walkthroughs/RayEtAl2020/Conversion.html new file mode 100644 index 00000000..36d52dc6 --- /dev/null +++ b/Userdocs/Walkthroughs/RayEtAl2020/Conversion.html @@ -0,0 +1,1435 @@ + + + + + + + + + + + Converting to NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Converting to NeuroML#

+

On inspection of the model, we see that it has two biophysically detailed cell models:

+
    +
  • the GGN (Giant GABAergic Neuron)

  • +
  • the KC (Kenyon cell)

  • +
+
+

Converting the Giant GABAergic Neuron#

+
+

Step 1) Exporting morphology of the GGN#

+

Let’s start with the GGN first. +It’s morphology is defined as an SWC file in this file. +One can download this file and view the morphology in a tool, like the HBP morphology viewer.

+
+Screen shot showing visualisation of the GGN in the HBP morphology viewer +
+

Fig. 66 Visualisation of the GGN in the HBP morphology viewer.#

+
+
+

A NEURON HOC script that includes the full morphology and the biophysics is also included.

+

Let us export the morphology first. +pyNeuroML includes the export_to_neuroml2 helper function that exports a cell model in NEURON to NeuroML. +We can write a short script to use this function to export the morphology from the provided HOC script.

+
#!/usr/bin/env python3
+"""
+Convert cell morphology to NeuroML.
+
+We only export morphologies here. We add the biophysics manually.
+
+File: NeuroML2/scripts/cell2nml.py
+"""
+
+import os
+import sys
+
+import pyneuroml
+from pyneuroml.neuron import export_to_neuroml2
+from neuron import h
+
+
+def main(acell):
+    """Main runner method.
+
+    :param acell: name of cell
+    :returns: None
+
+    """
+    loader_hoc_file = f"{acell}_loader.hoc"
+    loader_hoc_file_txt = """
+    /*load_file("nrngui.hoc")*/
+    load_file("stdrun.hoc")
+    xopen("../../NEURON/mb/cell_templates/GGN_20170309_sc.hoc")
+    objref cell
+    cell = new GGN_20170309_sc()
+    """
+
+    with open(loader_hoc_file, 'w') as f:
+        print(loader_hoc_file_txt, file=f)
+
+    export_to_neuroml2(loader_hoc_file, f"{acell}.morph.cell.nml",
+                       includeBiophysicalProperties=False, validate=False)
+
+    os.remove(loader_hoc_file)
+    # Note--a couple of diameters are 0.0, modified to 0.001 to validate the
+    # model
+
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
+        print("This script only accepts one argument.")
+        sys.exit(1)
+    main(sys.argv[1])
+
+
+

What we’re doing here is using the HOC script to build the cell model in NEURON, and then exporting it to NeuroML. +Calling it as python cellmorph2nml.py GGN will create a new file: GGN.morph.cell.nml which contains the morphology of the cell in NeuroML format. +Note that while export_to_neuroml2 does allow exporting the biophysics of the cell, it is better to add these manually later once one has gone through and converted the required ion channels and so on.

+

We can visualise the morphology using the pyNeuroML tools:

+
pynml-plotmorph -i GGN.morph.cell.nml
+
+
+
+Screen shot showing visualisation of the GGN using `pynml-plotmorph` +
+

Fig. 67 Visualisation of the GGN using pynml-plotmorph#

+
+
+
+
+

Step 2) Adding biophysics to the GGN#

+

Now that we have the morphology of the GGN exported, we can add the biophysics. +We need to inspect the original model code to learn about the biophysics. +In this model, for the GGN cell, the biophysics are included in the HOC script:

+
proc biophys() {
+  forsec all {
+    Ra = 100.0
+    cm = 1
+    insert pas
+      g_pas = 0.03e-3   // S/cm2 - as per Laurent et al 1990 RM = 33kohm-cm2
+      e_pas = -51
+  }
+}
+
+
+

As we see here, this is a passive cell without any ion channels. +To add the biophysics, we write a simple Python script that will make use of the pyNeuroML API. +The complete script is present in the repository:

+
def load_and_setup_cell(cellname: str):
+    """Load a cell, and clean it to prepare it for further modifications.
+
+    These operations are common for all cells.
+
+    :param cellname: name of cell.
+        the file containing the cell should then be <cell>.morph.cell.nml
+    :returns: document with cell
+    :rtype: neuroml.NeuroMLDocument
+
+    """
+    celldoc = read_neuroml2_file(
+        f"{cellname}.morph.cell.nml"
+    )  # type: neuroml.NeuroMLDocument
+    cell = celldoc.cells[0]  # type: neuroml.Cell
+    celldoc.networks = []
+    cell.id = cellname
+    cell.notes = cell.notes.replace("GGN_20170309_sc_0_0", cellname)
+    cell.notes += ". Reference: Subhasis Ray, Zane N Aldworth, Mark A Stopfer (2020) Feedback inhibition and its control in an insect olfactory circuit eLife 9:e53281."
+
+    [
+        default_all_group,
+        default_soma_group,
+        default_dendrite_group,
+        default_axon_group,
+    ] = cell.setup_default_segment_groups(
+        use_convention=True,
+        default_groups=["all", "soma_group", "dendrite_group", "axon_group"],
+    )
+
+    # populate default groups
+    for sg in cell.morphology.segment_groups:
+        if "soma" in sg.id and sg.id != "soma_group":
+            default_soma_group.add(neuroml.Include(segment_groups=sg.id))
+        if "axon" in sg.id and sg.id != "axon_group":
+            default_axon_group.add(neuroml.Include(segment_groups=sg.id))
+        if "dend" in sg.id and sg.id != "dendrite_group":
+            default_dendrite_group.add(neuroml.Include(segment_groups=sg.id))
+
+    cell.optimise_segment_groups()
+
+    return celldoc
+
+
+def postprocess_GGN():
+    """Post process GGN and add biophysics."""
+    cellname = "GGN"
+    celldoc = load_and_setup_cell(cellname)
+    cell = celldoc.cells[0]  # type: neuroml.Cell
+
+    # biophysics
+    # all
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="pas",
+        ion_channel="pas",
+        cond_density="0.00003 S_per_cm2",
+        erev="-51 mV",
+        group_id="all",
+        ion="non_specific",
+        ion_chan_def_file="channels/pas.channel.nml",
+    )
+    cell.set_resistivity("0.1 kohm_cm", group_id="all")
+    cell.set_specific_capacitance("1 uF_per_cm2", group_id="all")
+    cell.set_init_memb_potential("-80mV")
+
+    # L1 validation
+    # cell.validate(recursive=True)
+    cell.summary(morph=False, biophys=True)
+    # use pynml writer to also run L2 validation
+    write_neuroml2_file(celldoc, f"{cellname}.cell.nml")
+
+
+

The load_and_setup_cell function does some basic clean up and set up of the cell. +It ensures that the various segments that were exported from NEURON are placed into the conventional segment groups. +The postprocess_GGN function then adds the passive biophysics to the cell.

+

The pas channel is a standard implementation of a passive ion channel. +The rest are membrane properties–resistivity, specific capacitance and so on. +Once this is set up, we write the cell to a new file.

+

The GGN cell has now been converted. +Since the GGN is a simple passive cell, we won’t test its biophysics just yet.

+
+
+
+

Converting the Kenyon Cell#

+

The KC cell is defined in the kc_1_comp.hoc file. +Whereas the GGN cell had a complex morphology but passive biophysics, the KC cell has very simple morphology—a single compartment—but does contain active channels:

+
create soma
+
+
+objref all
+proc subsets() { local i
+  objref all
+  all = new SectionList()
+  soma all.append()
+}
+proc geom() {
+     soma {  // Total Cm = 4 pF
+        L = 6.366
+        diam = 20
+    }
+}
+
+proc biophys() {
+  forsec all {
+    Ra = 35.4
+    cm = 1
+    insert pas
+      g_pas = 9.75e-5         // S/cm2
+      e_pas = -70             // mV
+    insert kv
+      gbar_kv = 1.5e-3       // S/cm2
+    insert ka
+      gbar_ka = 1.4525e-2    // S/cm2
+    insert kst
+      gbar_kst = 2.0275e-3   // S/cm2
+    insert naf
+      gbar_naf = 3.5e-2      // S/cm2
+    insert nas
+      gbar_nas = 3e-3        // S/cm2
+      ek = -81.0             // mV
+      ena = 58.0               // mV
+  }
+}
+
+
+
+

Step 1) Converting ion channels#

+

For this cell, we will first convert the various ion channel models. +These are included in the mod folder. +An inspection tells us that these are all Hodgkin-Huxley type ion channels that use similar formalisms.

+

The first thing to do is to generate plots of time courses and steady states of the various ion channels. +These can be done easily using pynml-modchananalysis command line tool included in pyNeuroML. +We begin with the nas channel:

+
pynml-modchananalysis -modFile nas_wustenberg.mod nas
+
+
+

This will generate two plots, one for the steady state dynamics (inf), and one for the time course (tau) for activation variables in the channels:

+
+Image showing time course of activation variables of nas channel, generated with pynml-modchananalysis +
+

Fig. 68 Time course of activation variables of nas channel, generated with pynml-modchananalysis#

+
+
+
+Image showing steady state dynamics of activation variables of nas channel, generated with pynml-modchananalysis +
+

Fig. 69 Steady state dynamics of activation variables of nas channel, generated with pynml-modchananalysis#

+
+
+

The mod file defining the nas channel is shown below:

+

Here we have the m and h activation variables. +Although they are described in the standard Hodgkin Huxley formalism, in the settables procedure, we can see that their values are only calculated in the range of -120mV to 40mV. +The value does not change beyond 40mV. +This could be done for a number of reasons. +Perhaps the cell’s membrane potential does not go beyond 40mV.

+

We will attempt to remain faithful to the mod file in our conversion, so we will also incorporate this feature.

+

Since we know this is a Hodgkin Huxley type channel, we can search the schema to see if there are any elements that can describe it. +A search shows us that the ionChannelHH component type exists in the schema/standard. +In the schema, this is identical to ionChannel. +The usage examples included in the documentation indicate that we can use these elements from the standard to describe the ion channel here. +We need to:

+
    +
  • include the m gate, which has 3 sub units (m^3)

  • +
  • include the h gate, which has 1 sub unit (h^1)

  • +
  • formalise the equations that are used to calculate the steady state (inf)and time course (tau) for these gates/activation variables.

  • +
+

To begin with, let us ignore the restriction included in the mod file at 40mV. +Our NeuroML description will look something like this:

+
<ionChannel id="nas" type="ionChannelHH" conductance="1pS" species="na">
+
+<!-- some more details to be added here -->
+
+</ionChannelHH>
+
+
+

Now, there are number of different ways of expressing the dynamics of the activation variables. +(See this page for an introduction to HH formalism). +One can use the values of the forward and reverse rates (called alpha and beta in general) to calculate the steady state and time course. +Another possibility is that alpha and beta are not given, and instead the equations for the steady state and time course are. +The latter is the case here:

+
inf = 1 / ( 1 + exp((Vh - V) / s) )
+
+
+

If the rates are given, one can use the gateHHrates component type from the standard. +If the steady state and time course are, we can use gateHHtauInf. +There are also other components that can be used if a combination of rates and/or steady state and time course are given.

+

The equation above is in the form of a sigmoid function. +Another search in the standard shows us that we have the HHSigmoidVariable component type that can be used to represent a rate that is a sigmoid function. +The dynamics tab tells us that the equation is represented as:

+
x = rate / (1 + exp(0 - (v - midpoint)/scale))
+
+
+

Putting the equation for minf and hinf together with this form:

+
x = rate / (1 + exp(0 - (v - midpoint)/scale))
+minf  = 1.0 / (1 + exp((-30.1 - v) / 6.65))
+hinf  = 1.0 / (1 + exp((v + 51.4) / 5.9 ))
+
+
+

We can see that for minf, rate = 1 per ms, scale = 6.65mV and midpoint = -30.1mV. +Similarly, for hinf, rate = 1 per ms, scale = -5.9mV and midpoint = -51.4mV.

+
<ionChannel id="nas" type="ionChannelHH" conductance="1pS" species="na">
+
+    <gate id="m" instances="3" type="gateHHtauInf">
+        <steadyState type="HHSigmoidVariable" midpoint="-30.1mV" scale="6.65mV" rate="1" />
+        <timeCourse />
+    </gate>
+
+    <gate id="h" instances="1" type="gateHHtauInf">
+        <steadyState type="HHSigmoidVariable" midpoint="-51.4mV" scale="-5.9mV" rate="1" />
+        <timeCourse />
+    </gate>
+</ionChannel>
+
+
+

The time course is given by:

+
taum = (taumax - taumin) / (1 + exp((V - Vh1) / s1)) + taumin
+
+
+

Even though this is also a sigmoid, it is not, unfortunately, a standard form. +A component type does not exist in the NeuroML standard that can encapsulate this form +(It has more parameters, and has an additional + taumin).

+

This is not a problem, though, because NeuroML can be easily extended using LEMS. +We can write a new component type to encapsulate these dynamics based on the LEMS definition of the HHSigmoidVariable component type:

+
<ComponentType name="HHSigmoidVariable"
+               extends="baseHHVariable"
+               description="Sigmoidal form for variable equation">
+    <Dynamics>
+        <DerivedVariable name="x" dimension="none" exposure="x" value="rate / (1 + exp(0 - (v - midpoint)/scale))"/>
+    </Dynamics>
+</ComponentType>
+
+
+

Our new component will be this, and we will save it in a different file that we can then “include” in the nas channel definition file:

+
<!-- Saved as RayTau.nml -->
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2beta4.xsd" id="NeuroML_ionChannel">
+
+    <ComponentType name="Ray_tau"
+                  extends="baseVoltageDepTime"
+                  description="Tau parameter">
+
+        <Parameter name="max_tau" dimension="time"/>
+        <Parameter name="min_tau" dimension="time"/>
+        <Parameter name="midpoint" dimension="voltage"/>
+        <Parameter name="scale" dimension="voltage"/>
+        <Dynamics>
+            <DerivedVariable name="t" dimension="time" exposure="t" value="(((max_tau - min_tau) / (1 + exp(0 - (v - midpoint) / scale))) + min_tau)"/>
+        </Dynamics>
+    </ComponentType>
+</neuroml>
+
+
+

Note that it is very similar to the HHSigmoidVariable definition. +The only difference is that we have had to define additional parameters to use in our equation. +Also note that HHSigmoidVariable extends baseHHVariable which extends baseVoltageDepVariable. +However, since we know that tau is a time value, we extend the baseVoltageDepTime component type instead. +This is very similar to baseVoltageDepVariable, but is designed for component types producing time values, such as the time course here.

+

We save this as a different component type (a class), and we will provide it parameters to create our time courses for both m and h activation variables. +Our completed file will look like this:

+
<!-- saved as nas.channel.nml -->
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2beta4.xsd" id="NeuroML_ionChannel">
+
+    <notes>NeuroML file containing a single ion channel</notes>
+    <include href="RayTau.nml" />
+
+    <ionChannel id="nas" type="ionChannelHH" conductance="1pS" species="na">
+
+        <gate id="m" instances="3" type="gateHHtauInf">
+            <steadyState type="HHSigmoidVariable" midpoint="-30.1mV" scale="6.65mV" rate="1" />
+            <timeCourse type="Ray_tau" min_tau="0.83 ms" max_tau="0.093 ms" midpoint="-20.3 mV" scale="6.45mV"/>
+        </gate>
+
+        <gate id="h" instances="1" type="gateHHtauInf">
+            <steadyState type="HHSigmoidVariable" midpoint="-51.4mV" scale="-5.9mV" rate="1" />
+            <timeCourse type="Ray_tau" min_tau="1.9 ms" max_tau="12.24 ms" midpoint="-32.6 mV" scale="-8.0mV"/>
+        </gate>
+    </ionChannel>
+
+</neuroml>
+
+
+

Running pynml-channelanalysis nas.nml will generate the graphs for the steady state and time course from our channel definition, and you will see that these are the same as the graphs we generated from the mod files.

+

We are almost there, but we have a little more work to do here. +Remember that the original mod file limited the value of steady state at 40mV? +We have not incorporated that into our channel file yet.

+

Since the HHSigmoidVariable we have used for the steady state does not allow multiple equations, we will write a new component type for the steady state also:

+
<?xml version="1.0" encoding="ISO-8859-1"?>
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2beta4.xsd" id="NeuroML_ionChannel">
+
+    <ComponentType name="Ray_inf"
+        extends="baseVoltageDepVariable"
+        description="Inf parameter for Ray et al 2020" >
+
+        <Constant name="table_max" dimension="voltage" value="40 mV"/>
+        <Parameter name="rate" dimension="none"/>
+        <Parameter name="midpoint" dimension="voltage"/>
+        <Parameter name="scale" dimension="voltage"/>
+        <Dynamics>
+            <ConditionalDerivedVariable name="x" dimension="per_time" exposure="x">
+                <Case condition="v .gt. table_max" value="(rate / (1 + exp(0 - (table_max - midpoint) / scale)))"/>
+                <Case value="(rate / (1 + exp(0 - (v - midpoint) / scale)))"/>
+            </ConditionalDerivedVariable>
+        </Dynamics>
+    </ComponentType>
+<neuroml/>
+
+
+

The only difference here is that instead of the DerivedVariable, we have used a ConditionalDerivedVariable that allows conditional dynamics. +We have two cases here:

+
    +
  • if v is greater than table_max (which is 40mV), the rate is the value at v=40mV

  • +
  • otherwise, the rate is calculated from the value of v

  • +
+
+

1a) Kv, Naf, Kst#

+

The nas channel is now done. +If we look at the other channels—naf, kv, and kst—they follow similar formalisms. +So, we can re-use our newly created component types, Ray_inf and Ray_tau. +In fact, we consolidate them in a single file, RaySigmoid.nml, and “include” this in the channel definition files. +For example, here is kv.channel.nml:

+
<?xml version="1.0" encoding="ISO-8859-1"?>
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2beta4.xsd" id="NeuroML_ionChannel">
+
+    <notes>NeuroML file containing a single ion channel</notes>
+    <include href="RaySigmoid.nml" />
+
+    <ionChannel id="kv" conductance="1pS" type="ionChannelHH" species="k">
+
+        <notes>
+                Implementation of A type K+ channel ( KV ) from Wustenberg DG, Boytcheva M, Grunewald B, Byrne JH, Menzel R, Baxter DA.
+                This is a delayed rectifier type K+ channel in Apis mellifera Kenyon cells (cultured).
+        </notes>
+
+        <!-- custom component types because the tables in the mod files only go to 40 -->
+        <gate id="m" type="gateHHtauInf" instances="4">
+            <steadyState type="Ray_inf" rate="1.0" midpoint="-37.6mV" scale="27.24mV"/>
+            <timeCourse type="Ray_tau" min_tau="1.85 ms" max_tau="3.53 ms" midpoint="45.0 mV" scale="-13.71mV"/>
+        </gate>
+
+    </ionChannel>
+</neuroml>
+
+
+

Plots for the steady state and time course are:

+
+Image showing steady state dynamics of activation variables of kv channel, generated with pynml-channelanalysis +
+

Fig. 70 Steady state dynamics of activation variables of kv channel, generated with pynml-channelanalysis#

+
+
+
+Image showing time course of activation variables of kv channel, generated with pynml-channelanalysis +
+

Fig. 71 Time course of activation variables of kv channel, generated with pynml-channelanalysis#

+
+
+

In these graphs, the effect of the conditional at 40mV becomes more apparent.

+
+
+

1b) Ka#

+

The last remaining channel is the ka channel. +It’s dynamics are defined in the mod file as:

+
PROCEDURE settables(v (mV)) { 
+UNITSOFF
+        TABLE minf, hinf, mtau, htau FROM -120 TO 40 WITH 641
+        minf  = 1.0 / (1 + exp((-20.1 - v)/16.1))
+        hinf  = 1.0 / ( 1 + exp( ( v + 74.7 ) / 7 ) )
+        mtau = (1.65 - 0.35) / ((1 + exp(- (v + 70) / 4.0)) * (1 + exp((v + 20) / 12.0))) + 0.35
+        htau = (90 - 2.5) / ((1 + exp(- (v + 60) / 25.0)) * (1 + exp((v + 62) / 16.0))) + 2.5
+UNITSON
+}
+
+
+

The steady state here follows the same formalism, but the time course does not. +So, we need to create new component type to encapsulate the time courses here, similar to the Ray_tau component type that we did before:

+
    <ComponentType name="Ray_ka_tau"
+                   extends="baseVoltageDepTime"
+                   description="Tau parameter to describe ka">
+
+        <Parameter name="max_tau" dimension="time"/>
+        <Parameter name="min_tau" dimension="time"/>
+        <Parameter name="midpoint1" dimension="voltage"/>
+        <Parameter name="scale1" dimension="voltage"/>
+        <Parameter name="midpoint2" dimension="voltage"/>
+        <Parameter name="scale2" dimension="voltage"/>
+        <Constant name="table_max" dimension="voltage" value="40 mV"/>
+        <Dynamics>
+            <ConditionalDerivedVariable name="t" dimension="time" exposure="t" >
+                <Case condition="v .gt. table_max" value="(max_tau - min_tau) / ((1 + exp(-(table_max + midpoint1) / scale1)) * ( 1 + exp((table_max + midpoint2) / scale2))) + min_tau"/>
+                <Case value="(max_tau - min_tau) / ((1 + exp(-(v + midpoint1) / scale1)) * ( 1 + exp((v + midpoint2) / scale2))) + min_tau"/>
+
+            </ConditionalDerivedVariable>
+        </Dynamics>
+    </ComponentType>
+
+
+

We also add this to our RaySigmoid.nml file. +The ka.channel.nml file will, finally, look like this:

+
<?xml version="1.0" encoding="ISO-8859-1"?>
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2beta4.xsd" id="NeuroML_ionChannel">
+
+    <notes>NeuroML file containing a single ion channel</notes>
+    <include href="RaySigmoid.nml" />
+
+    <ionChannel id="ka" conductance="1pS" type="ionChannelHH" species="k">
+
+        <notes>
+                Implementation of A type K+ channel ( KA ) from Wustenberg DG, Boytcheva M, Grunewald B, Byrne JH, Menzel R, Baxter DA.
+                This is transient A type K+ channel in Apis mellifera Kenyon cells (cultured).
+        </notes>
+
+        <!-- custom component types because the tables in the mod files only go to 40 -->
+        <gate id="m" type="gateHHtauInf" instances="3">
+            <timeCourse type="Ray_ka_tau" midpoint1="70mV" midpoint2="2.0mV" scale1="4.0mV" scale2="12.0mV" min_tau="0.35ms" max_tau="1.65ms"/>
+            <steadyState type="Ray_inf" rate="1.0" midpoint="-20.1mV" scale="16.1mV"/>
+        </gate>
+
+        <gate id="h" type="gateHHtauInf" instances="1">
+            <timeCourse type="Ray_ka_tau" midpoint1="60mV" midpoint2="62.0mV" scale1="25.0mV" scale2="16.0mV" min_tau="2.5ms" max_tau="90.0ms"/>
+            <steadyState type="Ray_inf" rate="1.0" midpoint="-74.7mV" scale="-7.0mV"/>
+        </gate>
+
+    </ionChannel>
+</neuroml>
+
+
+

That is all the ion channels converted.

+

The ion channels are usually the most involved to convert because one must understand their initial descriptions in the mod files. +Even though the NMODL language used in mod files does have a well defined structure, like general programming languages, it is free-flowing. +This means that different people can write the same dynamics in different ways. +On the other hand, NeuroML and LEMS are more formal with more strict structures, and once channels are converted to these formats, they are much easier to understand.

+
+
+
+

Step 2) Creating the morphology#

+

Since the morphology of the KC is a single compartment, we don’t need to export it from NEURON. +We can create it ourselves.

+

The morphology is given in the HOC script:

+
proc geom() {
+     soma {  // Total Cm = 4 pF
+        L = 6.366
+        diam = 20
+    }
+}
+
+
+

We can create this using a Python script:

+
    celldoc = component_factory(
+        "NeuroMLDocument", id="KC_doc"
+    )  # type: neuroml.NeuroMLDocument
+    cell = celldoc.add("Cell", id="KC", validate=False)  # type: neuroml.Cell
+    cell.setup_nml_cell()
+    cell.add_segment([0, 0, 0, 20], [0, 0, 6.366, 20], seg_type="soma")
+
+
+

The setup_nml_cell and add_segment methods are part of the Cell class in the standard API.

+

Now that we have the morphology and the ion channels for the KC, we can add the biophysics to the morphology to complete the cell:

+
    # biophysics
+    # all
+    cell.set_resistivity("35.4 ohm_cm", group_id="all")
+    cell.set_specific_capacitance("1 uF_per_cm2", group_id="all")
+    cell.set_init_memb_potential("-70mV")
+    cell.set_spike_thresh("-10mV")
+
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="pas",
+        ion_channel="pas",
+        cond_density="9.75e-5 S_per_cm2",
+        erev="-70 mV",
+        group_id="all",
+        ion="non_specific",
+        ion_chan_def_file="channels/pas.channel.nml",
+    )
+
+    # K
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="kv",
+        ion_channel="kv",
+        cond_density="1.5e-3 S_per_cm2",
+        erev="-81 mV",
+        group_id="all",
+        ion="k",
+        ion_chan_def_file="channels/kv.channel.nml",
+    )
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="ka",
+        ion_channel="ka",
+        cond_density="1.4525e-2 S_per_cm2",
+        erev="-81 mV",
+        group_id="all",
+        ion="k",
+        ion_chan_def_file="channels/ka.channel.nml",
+    )
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="kst",
+        ion_channel="kst",
+        cond_density="2.0275e-3 S_per_cm2",
+        erev="-81 mV",
+        group_id="all",
+        ion="k",
+        ion_chan_def_file="channels/kst.channel.nml",
+    )
+    # Na
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="naf",
+        ion_channel="naf",
+        cond_density="3.5e-2 S_per_cm2",
+        erev="58 mV",
+        group_id="all",
+        ion="na",
+        ion_chan_def_file="channels/naf.channel.nml",
+    )
+    cell.add_channel_density(
+        nml_cell_doc=celldoc,
+        cd_id="nas",
+        ion_channel="nas",
+        cond_density="3e-3 S_per_cm2",
+        erev="58 mV",
+        group_id="all",
+        ion="na",
+        ion_chan_def_file="channels/nas.channel.nml",
+    )
+
+
+

This completes the cell. +We export it to a NeuroML file.

+
+
+

Step 3) Testing the model#

+

Finally, we want to test our NeuroML conversion against the original cell to see that it exhibits the same dynamics. +The test_kc.py script runs a simple step current simulation with a single KC cell and shows its membrane potentials:

+
+Image showing the membrane potential of the NEURON implementation of the KC cell model with a step current. +
+

Fig. 72 The membrane potential of the NEURON implementation of the KC cell model with a step current.#

+
+
+

We write a quick simulation to reproduce these using our NeuroML model:

+
def step_current_omv_kc():
+    """Create a step current simulation OMV LEMS file"""
+    # read the cell file, modify it, write a new one
+    netdoc = read_neuroml2_file("KC.cell.nml")
+    kc_cell = netdoc.cells[0]
+    net = netdoc.add(neuroml.Network, id="KC_net", validate=False)
+    pop = net.add(neuroml.Population, id="KC_pop", component=kc_cell.id, size=1)
+
+    # should be same as test_kc.py
+    pg = netdoc.add(
+        neuroml.PulseGenerator(
+            id="pg", delay="100ms", duration="500ms",
+            amplitude="16pA"
+        )
+    )
+
+    # Add these to cells
+    input_list = net.add(
+        neuroml.InputList(id="input_list", component=pg.id, populations=pop.id)
+    )
+    aninput = input_list.add(
+        neuroml.Input(
+            id="0",
+            target="../%s[0]" % (pop.id),
+            destination="synapses",
+            segment_id="0",
+        )
+    )
+    write_neuroml2_file(netdoc, "KC.net.nml")
+
+    generate_lems_file_for_neuroml(
+        sim_id="KC_step_test",
+        target=net.id,
+        neuroml_file="KC.net.nml",
+        duration="700ms",
+        dt="0.01ms",
+        lems_file_name="LEMS_KC_step_test.xml",
+        nml_doc=netdoc,
+        gen_spike_saves_for_all_somas=True,
+        target_dir=".",
+        gen_saves_for_quantities={
+            "k.dat": ["KC_pop[0]/biophys/membraneProperties/kv/iDensity"]
+        },
+        copy_neuroml=False
+    )
+
+    data = run_lems_with_jneuroml_neuron(
+        "LEMS_KC_step_test.xml", load_saved_data=True, compile_mods=True
+    )
+
+    generate_plot(
+        xvalues=[data["t"]],
+        yvalues=[data["KC_pop[0]/v"]],
+        title="Membrane potential: KC",
+    )
+
+
+

This will generate graphs of the KC’s membrane potential.

+
+Image showing the membrane potential of the NeuroML implementation of the KC cell model with a step current. +
+

Fig. 73 The membrane potential of the NeuroML implementation of the KC cell model with a step current.#

+
+
+

As we can see, the membrane potentials look very similar. +In the next page, we will also set up some more validation tests to better verify that the NEURON and NeuroML implementations produce the same dynamics.

+

Since this writes a LEMS simulation file also, we can also run the LEMS file directly for later verification:

+
pynml LEMS_KC_step_test.xml -neuron -nogui
+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Walkthroughs/RayEtAl2020/OMV.html b/Userdocs/Walkthroughs/RayEtAl2020/OMV.html new file mode 100644 index 00000000..e1296ad3 --- /dev/null +++ b/Userdocs/Walkthroughs/RayEtAl2020/OMV.html @@ -0,0 +1,893 @@ + + + + + + + + + + + Adding OMV tests — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Adding OMV tests#

+

Now that we have converted the cell models to NeuroML, we want to ensure that we get the same behaviour from the NeuroML converted cell model as from the original NEURON code. +For this, we have the Open Source Model Validation (OMV) framework. +The idea here is that we write simple test files that omv will run, and we provide data that omv can check against to see if the tests results are correct.

+

We will add OMV tests for the KC here.

+
+

Step 1) Getting spike data from the NEURON model#

+

For omv to test the model against, we need to generate some spike data that it knows to be the expected values. +The test_kc.py script already provides us with the spike data. +So, we can run the script and note down the spike times in a Model Emergent Properties (MEP) file:

+
system: Testing a detailed cell
+
+experiments:
+  stepKC:
+    expected:
+      spike times: [144.45000000000556, 177.64999999997536, 210.29999999994567, 242.74999999991616, 275.0499999998868, 307.19999999985754, 339.2249999998284, 371.07499999979945, 402.74999999977064, 434.1499999997421, 465.2249999997138, 495.87499999968594, 525.9749999997221, 555.3499999998289, 583.8499999999326]
+
+# generated from test-kc.py
+
+
+
+
+

Step 2) Adding tests#

+

Next, we can write a OSB Model Test (OMT) file to test the model using the step current simulation we had written before:

+
target: LEMS_KC_step_test.xml
+engine: jNeuroML_NEURON
+mep: .test.kc.mep
+experiments:
+  stepKC:
+    observables:
+      spike times:
+        file:
+          path: KC_step_test.KC_pop.v.dat
+          columns: [0,1]
+          scaling: [1000,1000]
+        spike detection:
+          method: threshold
+          threshold: -10.
+        tolerance: 0.00
+
+
+

Note that we start with a tolerance of 0 here. +Let us run the test and see what we get:

+
$ omv test .test.kc.jnmlneuron.omt
+
+[omv]
+[omv] Running the tests defined in .test.kc.jnmlnrn.omt
+[omv] =================================================
+[omv]   Found 1 experiment(s) to run on engine: jNeuroML_NEURON
+[omv] PATH: :/home/asinha/.local/share/virtualenvs/neuroml-311-dev/bin
+[omv] Env vars: {'PYTHONPATH': '/home/asinha/local/lib/python/site-packages', 'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}
+[omv]   Running file ./LEMS_KC_step_test.xml with jNeuroML_NEURON, env: {'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}
+[omv]     Running the commands: [/usr/bin/jnml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml -neuron -nogui -run] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')})
+[omv]     Commands: ['/usr/bin/jnml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml', '-neuron', '-nogui', '-run'] completed successfully
+[omv]   Success with running jNeuroML_NEURON
+[omv]   Running checks for experiment: stepKC
+[omv]
+[omv] Comparison of
+                    (observed data): [143.95, 176.76, 209.23, 241.52, 273.66, 305.68, 337.57, 369.33, 400.94, 432.38, 463.62, 494.59999999999997, 525.28, 555.59, 585.45]
+                    and
+                    (expected data): [144.45000000000556, 177.64999999997536, 210.29999999994567, 242.74999999991616, 275.0499999998868, 307.19999999985754, 339.2249999998284, 371.07499999979945, 402.74999999977064, 434.1499999997421, 465.2249999997138, 495.87499999968594, 525.9749999997221, 555.3499999998289, 583.8499999999326]
+                    failed against tolerance 0
+[omv]   A better tolerance to try is: 0.005087969567027844
+[omv]       Observable                        Test Passed
+[omv]       --------------------------------------------------
+[omv]       spike times                            ✘
+[omv]       +++++++++++++++++++++ Error info ++++++++++++++++++
+[omv]        Return code: 0
+
+
+

We see that there’s a slight difference in the spike times we obtain from our implementation. +This is not unexpected. +Small variations in how the mod files are written, or how the morphology is set up can result in small variations in the spike times. +omv will suggest a tolerance value for us to use. +The smaller the tolerance, the better.

+

We update our file to use the suggested tolerance and re-run the test:

+
$ omv test .test.kc.jnmlnrn.omt
+[omv]
+[omv] Running the tests defined in .test.kc.jnmlnrn.omt
+[omv] =================================================
+[omv]   Found 1 experiment(s) to run on engine: jNeuroML_NEURON
+[omv] PATH: :/home/asinha/.local/share/virtualenvs/neuroml-311-dev/bin
+[omv] Env vars: {'PYTHONPATH': '/home/asinha/local/lib/python/site-packages', 'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}
+[omv]   Running file ./LEMS_KC_step_test.xml with jNeuroML_NEURON, env: {'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}
+[omv]     Running the commands: [/usr/bin/jnml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml -neuron -nogui -run] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')})
+[omv]     Commands: ['/usr/bin/jnml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml', '-neuron', '-nogui', '-run'] completed successfully
+[omv]   Success with running jNeuroML_NEURON
+[omv]   Running checks for experiment: stepKC
+[omv]
+[omv]       Observable                        Test Passed
+[omv]       --------------------------------------------------
+[omv]       spike times                            ✔
+[omv]
+[omv]                   =================================
+[omv]                   Test passed: .test.kc.jnmlnrn.omt
+
+
+

We can also add a simple validation test that will allow omv to validate the various NeuroML files in the repository:

+
target: "*.c*.nml"
+engine: jNeuroML_validate
+
+
+

One can run all the OMV tests in a repository at once:

+
$ omv all
+[omv] Python 3. Ignoring tests for non Py3 compatible engines: False
+[omv]
+[omv]
+[omv] Running the tests defined in ./.test.kc.jnmlnrn.omt
+[omv] ===================================================
+[omv]   Found 1 experiment(s) to run on engine: jNeuroML_NEURON
+[omv] PATH: :/home/asinha/.local/share/virtualenvs/neuroml-311-dev/bin
+[omv] Env vars: {'PYTHONPATH': '/home/asinha/local/lib/python/site-packages', 'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}
+[omv]   Running file ./LEMS_KC_step_test.xml with jNeuroML_NEURON, env: {'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}
+[omv]     Running the commands: [/usr/bin/jnml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml -neuron -nogui -run] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')})
+[omv]     Commands: ['/usr/bin/jnml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml', '-neuron', '-nogui', '-run'] completed successfully
+[omv]   Success with running jNeuroML_NEURON
+[omv]   Running checks for experiment: stepKC
+[omv]
+[omv]       Observable                        Test Passed
+[omv]       --------------------------------------------------
+[omv]       spike times                            ✔
+[omv]
+[omv]
+[omv]       [ Test 1 of 2 complete - failed so far: 0 ]
+[omv]
+[omv]
+[omv] Running the tests defined in ./.test.validate.omt
+[omv] =================================================
+[omv]   No mep file specified. Will only run simulation using: jNeuroML_validate
+[omv]   Found 1 experiment(s) to run on engine: jNeuroML_validate
+[omv]   Running with jNeuroML_validate, using: ['/usr/bin/jnml', '-validate', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.morph.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/KC.cell.nml']...
+[omv]     Running the commands: [/usr/bin/jnml -validate /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.morph.cell.nml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.cell.nml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/KC.cell.nml] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'JNML_HOME': PosixPath('/usr/bin')})
+[omv]     Commands: ['/usr/bin/jnml', '-validate', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.morph.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/KC.cell.nml'] completed successfully
+[omv]   Running checks for experiment: Dry run
+[omv]
+[omv]       Observable                        Test Passed
+[omv]       --------------------------------------------------
+[omv]       dry                                    ✔
+[omv]
+[omv]
+[omv]       [ Test 2 of 2 complete - failed so far: 0 ]
+[omv]
+[omv]                             -------------
+[omv]                             2 test(s) run
+[omv]                             -------------
+[omv]
+[omv]                           All tests passing!
+[omv]                           ==================
+
+
+
+
+

Step 3) Setting up continuous testing on GitHub Actions#

+

Now that we have set up OMV test, we want to set up “continuous testing” (CT). +What this means is that we want these test to run automatically whenever we make any changes. +On GitHub, we can do these using GitHub Actions.

+

To set up a GitHub Action, we need to set up a “workflow file” in the .github/workflows directory. +We create one called omv-ci.yml:

+
name: Continuous build using OMV
+
+on:
+  schedule:
+    - cron: "1 1 1 */2 *"
+  push:
+    branches: [ master, development, experimental ]
+  pull_request:
+    branches: [ master, development, experimental ]
+
+jobs:
+  build:
+
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: [ "3.8", "3.10"]
+        engine: [ jNeuroML_validate, jNeuroML_NEURON ]
+
+    steps:
+    - uses: actions/checkout@v4
+
+    - name: Set up Python  ${{ matrix.python-version }}
+      uses: actions/setup-python@v5
+      with:
+        python-version:  ${{ matrix.python-version }}
+
+    - name: Install OMV
+      run: |
+        pip install OSBModelValidation
+        pip install scipy sympy matplotlib cython pandas tables
+
+    - name: Run OMV tests on engine ${{ matrix.engine }}
+      run: |
+        omv all -V --engine=${{ matrix.engine }}
+
+    - name: OMV final version info
+      run: |
+        omv list -V # list installed engines
+        env
+
+
+

This installs OMV and runs all test using it in the repository. +Additionally, it tests this out on a couple of Python versions.

+

Now, whenever we make a change to the repository—either as a pull request, or as a direct push of a commit, these tests will be run immediately to tell us if the model is still working as it should. +These can be seen in the “actions” tab in the GitHub Repository.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Walkthroughs/RayEtAl2020/RayEtAl2020.html b/Userdocs/Walkthroughs/RayEtAl2020/RayEtAl2020.html new file mode 100644 index 00000000..7d854c66 --- /dev/null +++ b/Userdocs/Walkthroughs/RayEtAl2020/RayEtAl2020.html @@ -0,0 +1,666 @@ + + + + + + + + + + + Converting Ray et al 2020 to NeuroML — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Converting Ray et al 2020 to NeuroML

+ +
+
+ +
+
+
+ + + + +
+ +
+

Converting Ray et al 2020 to NeuroML#

+

This section documents the conversion of Ray et al 2020 [RAS20], which was originally implemented in NEURON, to NeuroML. +It broadly follows the steps outlined in the converting models section.

+

For any queries, please contact Ankur Sinha on any of the NeuroML channels.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Walkthroughs/RayEtAl2020/Setup.html b/Userdocs/Walkthroughs/RayEtAl2020/Setup.html new file mode 100644 index 00000000..da8326e4 --- /dev/null +++ b/Userdocs/Walkthroughs/RayEtAl2020/Setup.html @@ -0,0 +1,722 @@ + + + + + + + + + + + Setting up — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Setting up#

+
+

Step 1) Find the original model code#

+

The original code is published on ModelDB.

+
+
+

Step 2) Create GitHub and Open Source Brain accounts for sharing the code#

+
+

2a) Sign up to GitHub and Open Source Brain#

+

We signed in to GitHub and OSBv1

+
+
+

2b) Create GitHub repository#

+

ModelDB provides GitHub repositories for all its models now. +This model is available on GitHub here: ModelDBRepository/262670. +The Open Source Brain (OSB) organization on GitHub also keeps a “fork” of these repositories to allow users to easily add them to both Open Source Brain v1 and v2. +This fork is here, and is the one that we will work with: OpenSourceBrain/262670.

+

For the conversion, I (Ankur) created a fork of this repository with a new branch to work in: sanjayankur31/262670. +A pull request work flow was used to submit converted bits back to the repository.

+

The first step was to re-organise the code to prepare it for conversion. +All the existing code was moved to a new NEURON folder, and a new NeuroML2 folder set up to store the NeuroML version.

+
+
+

2c) Create Open Source Brain project#

+

A new project was created on OSBv1 and linked to the OSB repository: https://v1.opensourcebrain.org/projects/locust-mushroom-body.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/Userdocs/Walkthroughs/Walkthroughs.html b/Userdocs/Walkthroughs/Walkthroughs.html new file mode 100644 index 00000000..b83fb609 --- /dev/null +++ b/Userdocs/Walkthroughs/Walkthroughs.html @@ -0,0 +1,664 @@ + + + + + + + + + + + Walk throughs — NeuroML Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Walk throughs

+ +
+
+ +
+
+
+ + + + +
+ +
+

Walk throughs#

+

This chapter documents a number of real-world tasks for users to refer to.

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+ + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_downloads/54d9372f3c36e040552bd9cd5af44e43/Acnet-LEMS.png b/_downloads/54d9372f3c36e040552bd9cd5af44e43/Acnet-LEMS.png new file mode 100644 index 00000000..0bbf314c Binary files /dev/null and b/_downloads/54d9372f3c36e040552bd9cd5af44e43/Acnet-LEMS.png differ diff --git a/_images/09b056ba3bcee90926ca2d8092d94e42615a0c2169f2d563a24732ed19aaf577.png b/_images/09b056ba3bcee90926ca2d8092d94e42615a0c2169f2d563a24732ed19aaf577.png new file mode 100644 index 00000000..18ca19ca Binary files /dev/null and b/_images/09b056ba3bcee90926ca2d8092d94e42615a0c2169f2d563a24732ed19aaf577.png differ diff --git a/_images/10f7b384128918f1a4783bb32cf043728fd73a477f08fda6a6c09e9f49a0dd1d.png b/_images/10f7b384128918f1a4783bb32cf043728fd73a477f08fda6a6c09e9f49a0dd1d.png new file mode 100644 index 00000000..0c13d58f Binary files /dev/null and b/_images/10f7b384128918f1a4783bb32cf043728fd73a477f08fda6a6c09e9f49a0dd1d.png differ diff --git a/_images/1921130adb0e4a2f5e4ebd1edccbfa8c217b6321b08f07a04036b3eca21588d9.png b/_images/1921130adb0e4a2f5e4ebd1edccbfa8c217b6321b08f07a04036b3eca21588d9.png new file mode 100644 index 00000000..af0ea9da Binary files /dev/null and b/_images/1921130adb0e4a2f5e4ebd1edccbfa8c217b6321b08f07a04036b3eca21588d9.png differ diff --git a/_images/20231122-ACNet.png b/_images/20231122-ACNet.png new file mode 100644 index 00000000..8db2ed84 Binary files /dev/null and b/_images/20231122-ACNet.png differ diff --git a/_images/21da5d20d226f9ba010af0c85727743b7d0f604a11d927ff7b85e04705273bf6.png b/_images/21da5d20d226f9ba010af0c85727743b7d0f604a11d927ff7b85e04705273bf6.png new file mode 100644 index 00000000..705f9e9d Binary files /dev/null and b/_images/21da5d20d226f9ba010af0c85727743b7d0f604a11d927ff7b85e04705273bf6.png differ diff --git a/_images/2e1bea36fe18d51db608aa0f8ab5ea17531213bda9b78245318583898b1049c5.png b/_images/2e1bea36fe18d51db608aa0f8ab5ea17531213bda9b78245318583898b1049c5.png new file mode 100644 index 00000000..805a9e9d Binary files /dev/null and b/_images/2e1bea36fe18d51db608aa0f8ab5ea17531213bda9b78245318583898b1049c5.png differ diff --git a/_images/311f26e8521b553eb3294ccf6409e24912e380c92535323da32bd6aa0111080a.png b/_images/311f26e8521b553eb3294ccf6409e24912e380c92535323da32bd6aa0111080a.png new file mode 100644 index 00000000..cf93d8df Binary files /dev/null and b/_images/311f26e8521b553eb3294ccf6409e24912e380c92535323da32bd6aa0111080a.png differ diff --git a/_images/35387de40bb3779c6e78fd8b3b87dcd64e3e7aafd3790055adfb904c42de8715.png b/_images/35387de40bb3779c6e78fd8b3b87dcd64e3e7aafd3790055adfb904c42de8715.png new file mode 100644 index 00000000..cc90d67d Binary files /dev/null and b/_images/35387de40bb3779c6e78fd8b3b87dcd64e3e7aafd3790055adfb904c42de8715.png differ diff --git a/_images/39f32324242c88ea6fbae0ad8a168db12e69b5d4003d3aea56582b6a8dd6d1cd.png b/_images/39f32324242c88ea6fbae0ad8a168db12e69b5d4003d3aea56582b6a8dd6d1cd.png new file mode 100644 index 00000000..29650959 Binary files /dev/null and b/_images/39f32324242c88ea6fbae0ad8a168db12e69b5d4003d3aea56582b6a8dd6d1cd.png differ diff --git a/_images/486734328bf2595816a031df84ce456e26a3f31c3bce9e2f25b38ae50d9bf955.png b/_images/486734328bf2595816a031df84ce456e26a3f31c3bce9e2f25b38ae50d9bf955.png new file mode 100644 index 00000000..3db11d8b Binary files /dev/null and b/_images/486734328bf2595816a031df84ce456e26a3f31c3bce9e2f25b38ae50d9bf955.png differ diff --git a/_images/4a56a474313c1712b353a7a3f085449661b7fd7bd3ad4890b429cf4953c34026.png b/_images/4a56a474313c1712b353a7a3f085449661b7fd7bd3ad4890b429cf4953c34026.png new file mode 100644 index 00000000..1d4566e4 Binary files /dev/null and b/_images/4a56a474313c1712b353a7a3f085449661b7fd7bd3ad4890b429cf4953c34026.png differ diff --git a/_images/523586e534cca4ab457b29b08c7b91242a2585c1d118638969d1474917a40993.png b/_images/523586e534cca4ab457b29b08c7b91242a2585c1d118638969d1474917a40993.png new file mode 100644 index 00000000..517ddb91 Binary files /dev/null and b/_images/523586e534cca4ab457b29b08c7b91242a2585c1d118638969d1474917a40993.png differ diff --git a/_images/5532522cf7b99fb6f0dead129fa2c8e0c46d4a126add2a89309fec5a8405545b.png b/_images/5532522cf7b99fb6f0dead129fa2c8e0c46d4a126add2a89309fec5a8405545b.png new file mode 100644 index 00000000..3b70bac7 Binary files /dev/null and b/_images/5532522cf7b99fb6f0dead129fa2c8e0c46d4a126add2a89309fec5a8405545b.png differ diff --git a/_images/56d999547a37a2d351ead4521d2cd3a85d2739d8e00846d41c37a75edf9b698c.png b/_images/56d999547a37a2d351ead4521d2cd3a85d2739d8e00846d41c37a75edf9b698c.png new file mode 100644 index 00000000..58e1158e Binary files /dev/null and b/_images/56d999547a37a2d351ead4521d2cd3a85d2739d8e00846d41c37a75edf9b698c.png differ diff --git a/_images/65f04ed77b9509a582a77992bacb723f0ebc056e88ab96c78af71d744f2150dd.png b/_images/65f04ed77b9509a582a77992bacb723f0ebc056e88ab96c78af71d744f2150dd.png new file mode 100644 index 00000000..28077b22 Binary files /dev/null and b/_images/65f04ed77b9509a582a77992bacb723f0ebc056e88ab96c78af71d744f2150dd.png differ diff --git a/_images/6fa63944a2646426dff6ade512d68a6ba6a53b9b7057c9bcd55eea8f8e1dba21.png b/_images/6fa63944a2646426dff6ade512d68a6ba6a53b9b7057c9bcd55eea8f8e1dba21.png new file mode 100644 index 00000000..12ffe4e4 Binary files /dev/null and b/_images/6fa63944a2646426dff6ade512d68a6ba6a53b9b7057c9bcd55eea8f8e1dba21.png differ diff --git a/_images/7d2474292dcb2b6a573030e67d9af7d7e579e2c3d8e56c1e32a56d343a0becb7.png b/_images/7d2474292dcb2b6a573030e67d9af7d7e579e2c3d8e56c1e32a56d343a0becb7.png new file mode 100644 index 00000000..a9613b02 Binary files /dev/null and b/_images/7d2474292dcb2b6a573030e67d9af7d7e579e2c3d8e56c1e32a56d343a0becb7.png differ diff --git a/_images/Acnet-matrix-1.png b/_images/Acnet-matrix-1.png new file mode 100644 index 00000000..924e87e0 Binary files /dev/null and b/_images/Acnet-matrix-1.png differ diff --git a/_images/Acnet-matrix-2.png b/_images/Acnet-matrix-2.png new file mode 100644 index 00000000..ae361ee5 Binary files /dev/null and b/_images/Acnet-matrix-2.png differ diff --git a/_images/Acnet-matrix-3.png b/_images/Acnet-matrix-3.png new file mode 100644 index 00000000..673bef42 Binary files /dev/null and b/_images/Acnet-matrix-3.png differ diff --git a/_images/Acnet-matrix-4.png b/_images/Acnet-matrix-4.png new file mode 100644 index 00000000..97a1ba3a Binary files /dev/null and b/_images/Acnet-matrix-4.png differ diff --git a/_images/Acnet-matrix-5.png b/_images/Acnet-matrix-5.png new file mode 100644 index 00000000..31d11979 Binary files /dev/null and b/_images/Acnet-matrix-5.png differ diff --git a/_images/Acnet-medium-graph-level1.png b/_images/Acnet-medium-graph-level1.png new file mode 100644 index 00000000..6d6248b6 Binary files /dev/null and b/_images/Acnet-medium-graph-level1.png differ diff --git a/_images/Acnet-medium-graph-level5.png b/_images/Acnet-medium-graph-level5.png new file mode 100644 index 00000000..f1537362 Binary files /dev/null and b/_images/Acnet-medium-graph-level5.png differ diff --git a/_images/Acnet-medium.net.png b/_images/Acnet-medium.net.png new file mode 100644 index 00000000..ab9341aa Binary files /dev/null and b/_images/Acnet-medium.net.png differ diff --git a/_images/Acnet-medium.povray.png b/_images/Acnet-medium.povray.png new file mode 100644 index 00000000..7240a75e Binary files /dev/null and b/_images/Acnet-medium.povray.png differ diff --git a/_images/EUS_200px.gif b/_images/EUS_200px.gif new file mode 100644 index 00000000..df4f5cfd Binary files /dev/null and b/_images/EUS_200px.gif differ diff --git a/_images/Figure6a.png b/_images/Figure6a.png new file mode 100644 index 00000000..d92cf449 Binary files /dev/null and b/_images/Figure6a.png differ diff --git a/_images/GGN-vispy.png b/_images/GGN-vispy.png new file mode 100644 index 00000000..6d9afd84 Binary files /dev/null and b/_images/GGN-vispy.png differ diff --git a/_images/GGN.png b/_images/GGN.png new file mode 100644 index 00000000..d5170d24 Binary files /dev/null and b/_images/GGN.png differ diff --git a/_images/HH_example_k_channel_1.png b/_images/HH_example_k_channel_1.png new file mode 100644 index 00000000..d139ae1b Binary files /dev/null and b/_images/HH_example_k_channel_1.png differ diff --git a/_images/HH_example_k_channel_2.png b/_images/HH_example_k_channel_2.png new file mode 100644 index 00000000..3ea7a4e7 Binary files /dev/null and b/_images/HH_example_k_channel_2.png differ diff --git a/_images/HH_example_na_channel_1.png b/_images/HH_example_na_channel_1.png new file mode 100644 index 00000000..652fa744 Binary files /dev/null and b/_images/HH_example_na_channel_1.png differ diff --git a/_images/HH_example_na_channel_2.png b/_images/HH_example_na_channel_2.png new file mode 100644 index 00000000..5e53a776 Binary files /dev/null and b/_images/HH_example_na_channel_2.png differ diff --git a/_images/HH_single_compartment_example_sim-i.png b/_images/HH_single_compartment_example_sim-i.png new file mode 100644 index 00000000..e5d89073 Binary files /dev/null and b/_images/HH_single_compartment_example_sim-i.png differ diff --git a/_images/HH_single_compartment_example_sim-iden.png b/_images/HH_single_compartment_example_sim-iden.png new file mode 100644 index 00000000..0459c657 Binary files /dev/null and b/_images/HH_single_compartment_example_sim-iden.png differ diff --git a/_images/HH_single_compartment_example_sim-v.png b/_images/HH_single_compartment_example_sim-v.png new file mode 100644 index 00000000..1e4c3ad0 Binary files /dev/null and b/_images/HH_single_compartment_example_sim-v.png differ diff --git a/_images/Ih-combined.png b/_images/Ih-combined.png new file mode 100644 index 00000000..cec0f10c Binary files /dev/null and b/_images/Ih-combined.png differ diff --git a/_images/IzNet-1.gv.png b/_images/IzNet-1.gv.png new file mode 100644 index 00000000..d30cb405 Binary files /dev/null and b/_images/IzNet-1.gv.png differ diff --git a/_images/IzNet.gv.png b/_images/IzNet.gv.png new file mode 100644 index 00000000..3a92d114 Binary files /dev/null and b/_images/IzNet.gv.png differ diff --git a/_images/KC-NEURON.png b/_images/KC-NEURON.png new file mode 100644 index 00000000..17d0f83c Binary files /dev/null and b/_images/KC-NEURON.png differ diff --git a/_images/KC-NeuroML.png b/_images/KC-NeuroML.png new file mode 100644 index 00000000..49be59f4 Binary files /dev/null and b/_images/KC-NeuroML.png differ diff --git a/_images/LEMS_example_izhikevich2007network_sim.png b/_images/LEMS_example_izhikevich2007network_sim.png new file mode 100644 index 00000000..e50f85ee Binary files /dev/null and b/_images/LEMS_example_izhikevich2007network_sim.png differ diff --git a/_images/MorphologyNeuroML2.png b/_images/MorphologyNeuroML2.png new file mode 100644 index 00000000..bede57a3 Binary files /dev/null and b/_images/MorphologyNeuroML2.png differ diff --git a/_images/NML-DB.png b/_images/NML-DB.png new file mode 100644 index 00000000..108336b1 Binary files /dev/null and b/_images/NML-DB.png differ diff --git a/_images/NaTa.png b/_images/NaTa.png new file mode 100644 index 00000000..c9641124 Binary files /dev/null and b/_images/NaTa.png differ diff --git a/_images/NeuroML2_LEMS_Overview_web.svg b/_images/NeuroML2_LEMS_Overview_web.svg new file mode 100644 index 00000000..129e26cb --- /dev/null +++ b/_images/NeuroML2_LEMS_Overview_web.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_images/OSBv1.png b/_images/OSBv1.png new file mode 100644 index 00000000..f7ddc508 Binary files /dev/null and b/_images/OSBv1.png differ diff --git a/_images/Steady_state(s)_of_activation_variables_in_nas_at_6.3_degC.png b/_images/Steady_state(s)_of_activation_variables_in_nas_at_6.3_degC.png new file mode 100644 index 00000000..21ed1514 Binary files /dev/null and b/_images/Steady_state(s)_of_activation_variables_in_nas_at_6.3_degC.png differ diff --git a/_images/Steady_state(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png b/_images/Steady_state(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png new file mode 100644 index 00000000..bb1294ab Binary files /dev/null and b/_images/Steady_state(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png differ diff --git a/_images/Time_Course(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png b/_images/Time_Course(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png new file mode 100644 index 00000000..689d8f5a Binary files /dev/null and b/_images/Time_Course(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png differ diff --git a/_images/Time_course(s)_of_activation_variables_in_nas_at_6.3_degC.png b/_images/Time_course(s)_of_activation_variables_in_nas_at_6.3_degC.png new file mode 100644 index 00000000..0ab88897 Binary files /dev/null and b/_images/Time_course(s)_of_activation_variables_in_nas_at_6.3_degC.png differ diff --git a/_images/andrew.jpg b/_images/andrew.jpg new file mode 100644 index 00000000..97bb20aa Binary files /dev/null and b/_images/andrew.jpg differ diff --git a/_images/angus.png b/_images/angus.png new file mode 100644 index 00000000..9ee7976d Binary files /dev/null and b/_images/angus.png differ diff --git a/_images/ankur.png b/_images/ankur.png new file mode 100644 index 00000000..e4ab7d70 Binary files /dev/null and b/_images/ankur.png differ diff --git a/_images/arbor.png b/_images/arbor.png new file mode 100644 index 00000000..0ad800f8 Binary files /dev/null and b/_images/arbor.png differ diff --git a/_images/avrama.jpg b/_images/avrama.jpg new file mode 100644 index 00000000..6c20554a Binary files /dev/null and b/_images/avrama.jpg differ diff --git a/_images/b1d3fc1ed74d01cb82fe356e2a98ce3ecc57e951417ad2310ba7caa0587cc44c.png b/_images/b1d3fc1ed74d01cb82fe356e2a98ce3ecc57e951417ad2310ba7caa0587cc44c.png new file mode 100644 index 00000000..26429f8e Binary files /dev/null and b/_images/b1d3fc1ed74d01cb82fe356e2a98ce3ecc57e951417ad2310ba7caa0587cc44c.png differ diff --git a/_images/b2aa4981e8cb6b519d72cd0d1e76aa6759e3e3913d827eeee9b12defecf38c63.png b/_images/b2aa4981e8cb6b519d72cd0d1e76aa6759e3e3913d827eeee9b12defecf38c63.png new file mode 100644 index 00000000..4275532d Binary files /dev/null and b/_images/b2aa4981e8cb6b519d72cd0d1e76aa6759e3e3913d827eeee9b12defecf38c63.png differ diff --git a/_images/b2f5f0a7b7b908b19a44be5ea8289dfd0fe0d44b6e3017b6dbd63b20f3e06d2f.png b/_images/b2f5f0a7b7b908b19a44be5ea8289dfd0fe0d44b6e3017b6dbd63b20f3e06d2f.png new file mode 100644 index 00000000..808004e0 Binary files /dev/null and b/_images/b2f5f0a7b7b908b19a44be5ea8289dfd0fe0d44b6e3017b6dbd63b20f3e06d2f.png differ diff --git a/_images/b6da95dd80b21f297a7f10e0e0d2a1138c26f6aaa4a683d91e4e0827969083ac.png b/_images/b6da95dd80b21f297a7f10e0e0d2a1138c26f6aaa4a683d91e4e0827969083ac.png new file mode 100644 index 00000000..05125a3d Binary files /dev/null and b/_images/b6da95dd80b21f297a7f10e0e0d2a1138c26f6aaa4a683d91e4e0827969083ac.png differ diff --git a/_images/bbsrc.gif b/_images/bbsrc.gif new file mode 100644 index 00000000..61f56e63 Binary files /dev/null and b/_images/bbsrc.gif differ diff --git a/_images/bhalla.png b/_images/bhalla.png new file mode 100644 index 00000000..b9960403 Binary files /dev/null and b/_images/bhalla.png differ diff --git a/_images/biosimulators.png b/_images/biosimulators.png new file mode 100644 index 00000000..f833b6bb Binary files /dev/null and b/_images/biosimulators.png differ diff --git a/_images/boris.jpg b/_images/boris.jpg new file mode 100644 index 00000000..0d6960a7 Binary files /dev/null and b/_images/boris.jpg differ diff --git a/_images/brian2.png b/_images/brian2.png new file mode 100644 index 00000000..ca69fc9f Binary files /dev/null and b/_images/brian2.png differ diff --git a/_images/catmaid.png b/_images/catmaid.png new file mode 100644 index 00000000..60f5d05e Binary files /dev/null and b/_images/catmaid.png differ diff --git a/_images/cbcc1f3b0b4c7e625953206eac46859f31f199aa62d7a8ea9eb208ec67dda9c9.png b/_images/cbcc1f3b0b4c7e625953206eac46859f31f199aa62d7a8ea9eb208ec67dda9c9.png new file mode 100644 index 00000000..e40307c4 Binary files /dev/null and b/_images/cbcc1f3b0b4c7e625953206eac46859f31f199aa62d7a8ea9eb208ec67dda9c9.png differ diff --git a/_images/cgunay.JPG b/_images/cgunay.JPG new file mode 100644 index 00000000..b46e66d8 Binary files /dev/null and b/_images/cgunay.JPG differ diff --git a/_images/combine.png b/_images/combine.png new file mode 100644 index 00000000..a921386f Binary files /dev/null and b/_images/combine.png differ diff --git a/_images/crook2007-morphml-figure1.png b/_images/crook2007-morphml-figure1.png new file mode 100644 index 00000000..2fdab3cc Binary files /dev/null and b/_images/crook2007-morphml-figure1.png differ diff --git a/_images/cx3d.png b/_images/cx3d.png new file mode 100644 index 00000000..0c2561af Binary files /dev/null and b/_images/cx3d.png differ diff --git a/_images/d3d84013cc4343a3e29f989e171b2aa9d3a91931c647b322d965986c06ad3967.png b/_images/d3d84013cc4343a3e29f989e171b2aa9d3a91931c647b322d965986c06ad3967.png new file mode 100644 index 00000000..dbae10d8 Binary files /dev/null and b/_images/d3d84013cc4343a3e29f989e171b2aa9d3a91931c647b322d965986c06ad3967.png differ diff --git a/_images/d3f762fb7ec27fd7339831d1e89aa8dd8020512703457350a7edf9b4b328f4ff.png b/_images/d3f762fb7ec27fd7339831d1e89aa8dd8020512703457350a7edf9b4b328f4ff.png new file mode 100644 index 00000000..7f8c3817 Binary files /dev/null and b/_images/d3f762fb7ec27fd7339831d1e89aa8dd8020512703457350a7edf9b4b328f4ff.png differ diff --git a/_images/e7d9d45258035bf5b93bf809355fac7ebbf1889be2e005ea86bf616c5ae186cb.png b/_images/e7d9d45258035bf5b93bf809355fac7ebbf1889be2e005ea86bf616c5ae186cb.png new file mode 100644 index 00000000..71399d79 Binary files /dev/null and b/_images/e7d9d45258035bf5b93bf809355fac7ebbf1889be2e005ea86bf616c5ae186cb.png differ diff --git a/_images/ec193126c160d9b3a694a430ec1c3ce01ff44331eb30ff5cecfa6f5b966145d2.png b/_images/ec193126c160d9b3a694a430ec1c3ce01ff44331eb30ff5cecfa6f5b966145d2.png new file mode 100644 index 00000000..24b0fa51 Binary files /dev/null and b/_images/ec193126c160d9b3a694a430ec1c3ce01ff44331eb30ff5cecfa6f5b966145d2.png differ diff --git a/_images/endorsed.png b/_images/endorsed.png new file mode 100644 index 00000000..7cc0fc82 Binary files /dev/null and b/_images/endorsed.png differ diff --git a/_images/example-single-izhikevich2007cell-sim-v.png b/_images/example-single-izhikevich2007cell-sim-v.png new file mode 100644 index 00000000..92abde56 Binary files /dev/null and b/_images/example-single-izhikevich2007cell-sim-v.png differ diff --git a/_images/example_izhikevich2007network_sim-spikes.png b/_images/example_izhikevich2007network_sim-spikes.png new file mode 100644 index 00000000..2e010a37 Binary files /dev/null and b/_images/example_izhikevich2007network_sim-spikes.png differ diff --git a/_images/fb5a80742e218f1e3932e62a5e81cb3c1b8b113c9dc0e6a3645ac2459f3c02d7.png b/_images/fb5a80742e218f1e3932e62a5e81cb3c1b8b113c9dc0e6a3645ac2459f3c02d7.png new file mode 100644 index 00000000..08f8b598 Binary files /dev/null and b/_images/fb5a80742e218f1e3932e62a5e81cb3c1b8b113c9dc0e6a3645ac2459f3c02d7.png differ diff --git a/_images/fce843b119e9ef931e2fb37076f9f8b9a2f35cda36396498580c7374c2b8a456.png b/_images/fce843b119e9ef931e2fb37076f9f8b9a2f35cda36396498580c7374c2b8a456.png new file mode 100644 index 00000000..3980118f Binary files /dev/null and b/_images/fce843b119e9ef931e2fb37076f9f8b9a2f35cda36396498580c7374c2b8a456.png differ diff --git a/_images/fitted_izhikevich_fitness.png b/_images/fitted_izhikevich_fitness.png new file mode 100644 index 00000000..270827b0 Binary files /dev/null and b/_images/fitted_izhikevich_fitness.png differ diff --git a/_images/fitted_izhikevich_hist.png b/_images/fitted_izhikevich_hist.png new file mode 100644 index 00000000..5cb9d9eb Binary files /dev/null and b/_images/fitted_izhikevich_hist.png differ diff --git a/_images/fitted_izhikevich_output.png b/_images/fitted_izhikevich_output.png new file mode 100644 index 00000000..517bc229 Binary files /dev/null and b/_images/fitted_izhikevich_output.png differ diff --git a/_images/fitted_izhikevich_scatter.png b/_images/fitted_izhikevich_scatter.png new file mode 100644 index 00000000..305802fd Binary files /dev/null and b/_images/fitted_izhikevich_scatter.png differ diff --git a/_images/fitted_izhikevich_screenshot_nwbexplorer.png b/_images/fitted_izhikevich_screenshot_nwbexplorer.png new file mode 100644 index 00000000..4229f9e7 Binary files /dev/null and b/_images/fitted_izhikevich_screenshot_nwbexplorer.png differ diff --git a/_images/fitted_izhikevich_sim-exp-v.png b/_images/fitted_izhikevich_sim-exp-v.png new file mode 100644 index 00000000..b0e6fd45 Binary files /dev/null and b/_images/fitted_izhikevich_sim-exp-v.png differ diff --git a/_images/genesis.png b/_images/genesis.png new file mode 100644 index 00000000..f8f0e60e Binary files /dev/null and b/_images/genesis.png differ diff --git a/_images/geppetto.png b/_images/geppetto.png new file mode 100644 index 00000000..62d2024b Binary files /dev/null and b/_images/geppetto.png differ diff --git a/_images/hugo.png b/_images/hugo.png new file mode 100644 index 00000000..04637ab0 Binary files /dev/null and b/_images/hugo.png differ diff --git a/_images/incf.png b/_images/incf.png new file mode 100644 index 00000000..28afa0d0 Binary files /dev/null and b/_images/incf.png differ diff --git a/_images/izhikevich-binder.png b/_images/izhikevich-binder.png new file mode 100644 index 00000000..58d01b38 Binary files /dev/null and b/_images/izhikevich-binder.png differ diff --git a/_images/izhikevich-google.png b/_images/izhikevich-google.png new file mode 100644 index 00000000..1c3bf270 Binary files /dev/null and b/_images/izhikevich-google.png differ diff --git a/_images/izhikevich-livecode.png b/_images/izhikevich-livecode.png new file mode 100644 index 00000000..26a9f28b Binary files /dev/null and b/_images/izhikevich-livecode.png differ diff --git a/_images/izhikevich-rocket-options.png b/_images/izhikevich-rocket-options.png new file mode 100644 index 00000000..43d7c85c Binary files /dev/null and b/_images/izhikevich-rocket-options.png differ diff --git a/_images/izhikevich-rocket.png b/_images/izhikevich-rocket.png new file mode 100644 index 00000000..5a5fed4b Binary files /dev/null and b/_images/izhikevich-rocket.png differ diff --git a/_images/jupyter-download.png b/_images/jupyter-download.png new file mode 100644 index 00000000..bac9690e Binary files /dev/null and b/_images/jupyter-download.png differ diff --git a/_images/jupyterbook-issue.png b/_images/jupyterbook-issue.png new file mode 100644 index 00000000..90f05683 Binary files /dev/null and b/_images/jupyterbook-issue.png differ diff --git a/_images/lems-figure2.png b/_images/lems-figure2.png new file mode 100644 index 00000000..8eb338dc Binary files /dev/null and b/_images/lems-figure2.png differ diff --git a/_images/lems_example4.png b/_images/lems_example4.png new file mode 100644 index 00000000..968b5e04 Binary files /dev/null and b/_images/lems_example4.png differ diff --git a/_images/lems_example6.png b/_images/lems_example6.png new file mode 100644 index 00000000..00379d3b Binary files /dev/null and b/_images/lems_example6.png differ diff --git a/_images/lems_example7.png b/_images/lems_example7.png new file mode 100644 index 00000000..a4de00a1 Binary files /dev/null and b/_images/lems_example7.png differ diff --git a/_images/lems_nml_files.png b/_images/lems_nml_files.png new file mode 100644 index 00000000..993cf902 Binary files /dev/null and b/_images/lems_nml_files.png differ diff --git a/_images/lfpy.png b/_images/lfpy.png new file mode 100644 index 00000000..59f15553 Binary files /dev/null and b/_images/lfpy.png differ diff --git a/_images/libneuroml.png b/_images/libneuroml.png new file mode 100644 index 00000000..b441c0ad Binary files /dev/null and b/_images/libneuroml.png differ diff --git a/_images/lyle.png b/_images/lyle.png new file mode 100644 index 00000000..c4854a59 Binary files /dev/null and b/_images/lyle.png differ diff --git a/_images/mdf.png b/_images/mdf.png new file mode 100644 index 00000000..6a39f935 Binary files /dev/null and b/_images/mdf.png differ diff --git a/_images/michael.png b/_images/michael.png new file mode 100644 index 00000000..c73b08d9 Binary files /dev/null and b/_images/michael.png differ diff --git a/_images/moose.jpg b/_images/moose.jpg new file mode 100644 index 00000000..303a6b52 Binary files /dev/null and b/_images/moose.jpg differ diff --git a/_images/moose_mod.png b/_images/moose_mod.png new file mode 100644 index 00000000..52074eb1 Binary files /dev/null and b/_images/moose_mod.png differ diff --git a/_images/mrc.jpg b/_images/mrc.jpg new file mode 100644 index 00000000..e773dc81 Binary files /dev/null and b/_images/mrc.jpg differ diff --git a/_images/myokit.png b/_images/myokit.png new file mode 100644 index 00000000..c3c56189 Binary files /dev/null and b/_images/myokit.png differ diff --git a/_images/nest-logo.png b/_images/nest-logo.png new file mode 100644 index 00000000..29887df2 Binary files /dev/null and b/_images/nest-logo.png differ diff --git a/_images/netpyne.png b/_images/netpyne.png new file mode 100644 index 00000000..2d79c420 Binary files /dev/null and b/_images/netpyne.png differ diff --git a/_images/neuroconstruct.png b/_images/neuroconstruct.png new file mode 100644 index 00000000..b27bff46 Binary files /dev/null and b/_images/neuroconstruct.png differ diff --git a/_images/neuromldb-channel-analysis.png b/_images/neuromldb-channel-analysis.png new file mode 100644 index 00000000..f0c8bad8 Binary files /dev/null and b/_images/neuromldb-channel-analysis.png differ diff --git a/_images/neuron.png b/_images/neuron.png new file mode 100644 index 00000000..df09352e Binary files /dev/null and b/_images/neuron.png differ diff --git a/_images/neuronland.png b/_images/neuronland.png new file mode 100644 index 00000000..aaf234b8 Binary files /dev/null and b/_images/neuronland.png differ diff --git a/_images/neuronvisio.png b/_images/neuronvisio.png new file mode 100644 index 00000000..09da826e Binary files /dev/null and b/_images/neuronvisio.png differ diff --git a/_images/nih.gif b/_images/nih.gif new file mode 100644 index 00000000..5fc0d243 Binary files /dev/null and b/_images/nih.gif differ diff --git a/_images/nml-db-morphology.png b/_images/nml-db-morphology.png new file mode 100644 index 00000000..fb4bd5b8 Binary files /dev/null and b/_images/nml-db-morphology.png differ diff --git a/_images/nmllite-example.png b/_images/nmllite-example.png new file mode 100644 index 00000000..107a660a Binary files /dev/null and b/_images/nmllite-example.png differ diff --git a/_images/nsf.gif b/_images/nsf.gif new file mode 100644 index 00000000..ae5780cd Binary files /dev/null and b/_images/nsf.gif differ diff --git a/_images/olm-cell-fi.png b/_images/olm-cell-fi.png new file mode 100644 index 00000000..3cbba218 Binary files /dev/null and b/_images/olm-cell-fi.png differ diff --git a/_images/olm-cell-subthresholdVi.png b/_images/olm-cell-subthresholdVi.png new file mode 100644 index 00000000..10cf34ce Binary files /dev/null and b/_images/olm-cell-subthresholdVi.png differ diff --git a/_images/olm-cell-voltage-traces.png b/_images/olm-cell-voltage-traces.png new file mode 100644 index 00000000..1f221b16 Binary files /dev/null and b/_images/olm-cell-voltage-traces.png differ diff --git a/_images/olm.cell.png b/_images/olm.cell.png new file mode 100644 index 00000000..abc26537 Binary files /dev/null and b/_images/olm.cell.png differ diff --git a/_images/olm.cell.xy.png b/_images/olm.cell.xy.png new file mode 100644 index 00000000..e12fbe4b Binary files /dev/null and b/_images/olm.cell.xy.png differ diff --git a/_images/olm_example_sim_seg0_soma0-v.png b/_images/olm_example_sim_seg0_soma0-v.png new file mode 100644 index 00000000..5a8b1884 Binary files /dev/null and b/_images/olm_example_sim_seg0_soma0-v.png differ diff --git a/_images/openworm.png b/_images/openworm.png new file mode 100644 index 00000000..1a77138a Binary files /dev/null and b/_images/openworm.png differ diff --git a/_images/openworm2-mod.png b/_images/openworm2-mod.png new file mode 100644 index 00000000..e51c379b Binary files /dev/null and b/_images/openworm2-mod.png differ diff --git a/_images/osb-channel-analysis.png b/_images/osb-channel-analysis.png new file mode 100644 index 00000000..eba32807 Binary files /dev/null and b/_images/osb-channel-analysis.png differ diff --git a/_images/osb-conversion.png b/_images/osb-conversion.png new file mode 100644 index 00000000..a39b908b Binary files /dev/null and b/_images/osb-conversion.png differ diff --git a/_images/osb-morphology.png b/_images/osb-morphology.png new file mode 100644 index 00000000..e93ce8a8 Binary files /dev/null and b/_images/osb-morphology.png differ diff --git a/_images/osbnivo_mod2.png b/_images/osbnivo_mod2.png new file mode 100644 index 00000000..2e19103b Binary files /dev/null and b/_images/osbnivo_mod2.png differ diff --git a/_images/padraig2.jpeg b/_images/padraig2.jpeg new file mode 100644 index 00000000..d280206f Binary files /dev/null and b/_images/padraig2.jpeg differ diff --git a/_images/pynml-channelanalysis.png b/_images/pynml-channelanalysis.png new file mode 100644 index 00000000..c3d8e41c Binary files /dev/null and b/_images/pynml-channelanalysis.png differ diff --git a/_images/pynml_jnml.svg b/_images/pynml_jnml.svg new file mode 100644 index 00000000..2cef3dd4 --- /dev/null +++ b/_images/pynml_jnml.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_images/pynn.png b/_images/pynn.png new file mode 100644 index 00000000..7e63f3a8 Binary files /dev/null and b/_images/pynn.png differ diff --git a/_images/robertmcdougal.png b/_images/robertmcdougal.png new file mode 100644 index 00000000..058fab5b Binary files /dev/null and b/_images/robertmcdougal.png differ diff --git a/_images/rsz_crook.jpg b/_images/rsz_crook.jpg new file mode 100644 index 00000000..b5d9399e Binary files /dev/null and b/_images/rsz_crook.jpg differ diff --git a/_images/salva.png b/_images/salva.png new file mode 100644 index 00000000..2ecacb02 Binary files /dev/null and b/_images/salva.png differ diff --git a/_images/single_hh_cell_network.gv.png b/_images/single_hh_cell_network.gv.png new file mode 100644 index 00000000..3851fb96 Binary files /dev/null and b/_images/single_hh_cell_network.gv.png differ diff --git a/_images/single_olm_cell_network.gv.png b/_images/single_olm_cell_network.gv.png new file mode 100644 index 00000000..b9ff950e Binary files /dev/null and b/_images/single_olm_cell_network.gv.png differ diff --git a/_images/sotirios.jpg b/_images/sotirios.jpg new file mode 100644 index 00000000..09c27ea6 Binary files /dev/null and b/_images/sotirios.jpg differ diff --git a/_images/test_morphology_plot_2d_Cell_497232312_cell_nml_xy.png b/_images/test_morphology_plot_2d_Cell_497232312_cell_nml_xy.png new file mode 100644 index 00000000..37ce9744 Binary files /dev/null and b/_images/test_morphology_plot_2d_Cell_497232312_cell_nml_xy.png differ diff --git a/_images/trakem2.png b/_images/trakem2.png new file mode 100644 index 00000000..f4bdf9ae Binary files /dev/null and b/_images/trakem2.png differ diff --git a/_images/trees.png b/_images/trees.png new file mode 100644 index 00000000..c53bcfb1 Binary files /dev/null and b/_images/trees.png differ diff --git a/_images/tvb.png b/_images/tvb.png new file mode 100644 index 00000000..f550605f Binary files /dev/null and b/_images/tvb.png differ diff --git a/_images/wtlogo.png b/_images/wtlogo.png new file mode 100644 index 00000000..d9812ced Binary files /dev/null and b/_images/wtlogo.png differ diff --git a/_sources/404.md b/_sources/404.md new file mode 100644 index 00000000..cc1be30a --- /dev/null +++ b/_sources/404.md @@ -0,0 +1,5 @@ +# Page not found + +Sorry, the page you were looking could not be found. +Please use the search function to look for information in the documentation. +For any issues, please {ref}`contact us `. diff --git a/_sources/Devdocs/DevSOP.md b/_sources/Devdocs/DevSOP.md new file mode 100644 index 00000000..c8630c37 --- /dev/null +++ b/_sources/Devdocs/DevSOP.md @@ -0,0 +1,124 @@ +(devdocs:devsop)= +# Contribution guidelines + +Thank you for your interest in contributing to NeuroML. +Welcome! + +This page documents the contribution guidelines for all NeuroML related repositories. + +Please do remember that these are *guidelines* but not rules that must be strictly followed. +We think these are reasonable ideas to follow and they help us maintain a high code quality while making it easier and more efficient for all of us to work together. +However, there may be cases where they can not be followed, and that's fine too. + +(devdocs:devsop:coc)= +## Code of conduct + +All NeuroML projects are governed by the {ref}`Code of Conduct `. +By participating, you are expected to uphold this code. +Please report unacceptable behaviour to the moderators of the communication channel you are in. + +(devdocs:devsop:repos)= +## Structure of repositories + +- All NeuroML repositories use the [Git](https://git-scm.com/) version control system. +- Contributions are made using [pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). +- Each NeuroML software tool resides in its own GitHub repository under the [NeuroML GitHub Organization](https://github.com/NeuroML), apart from [libNeuroML](https://github.com/NeuralEnsemble/libNeuroML) which is developed in collaboration with the [NeuralEnsemble community](http://neuralensemble.org/) and so lives under their GitHub organization. +- LEMS repositories are housed under the [LEMS GitHub Organization](https://github.com/LEMS). + +You can find links to these on the respective pages for each {ref}`software tool `. + +The NeuroML standard itself (schema and ComponentType definitions) is housed in its own repository [here](https://github.com/NeuroML/NeuroML2). + +(devdocs:devsop:repos:zenhub) +### Kanban board on Zenhub + +An overview of the various repositories, tasks, issues, and so on can be seen on the [NeuroML Kanban board on Zenhub](https://app.zenhub.com/workspaces/neuroml-development-605c92c7c670460016e497ab/board?filterLogic=any&repos=7225220,6579766,7225426,299352189,78101103,129064858,8460738,6171449,6171626,27832592,78100679,6171646,3740176,4614078,7146844,4326891&showPipelineDescriptions=false). + + +(devdocs:devsop:versioning)= +## Versioning + +All NeuroML repositories (including the standard) follow [Semantic versioning](https://semver.org/). +This means that the version string consists of three components: `MAJOR.MINOR.PATCH`: + +- the MAJOR version is incremented when incompatible API changes are made, +- the MINOR version is incremented when functionality is added in a backwards compatible manner, and +- the PATCH version is incremented when backwards compatible bug fixes are made. + +(devdocs:devsop:branches)= +## Git branches + +- Please develop against the `development` branch in all repositories. + This branch is merged into `master` via a pull request when a new release is made. + This ensures that all tests are run at each step to verify correctness. + As a result, the `master` branch of all repositories holds the stable version of the standard and tools, while the `development` branch holds the next, unstable version that is being worked upon. + +- For branch names, please consider using the [Git flow](https://nvie.com/posts/a-successful-git-branching-model/) naming convention (not mandatory but strongly suggested): + + - prefix feature branches with `feat/` or `enh/` (for enhancement) + - prefix bugfix branches with `bugfix/` or `fix/` + - pull requests addressing specific tickets may also mention them in the branch name. E.g., `bugfix/issue-22`. + +(devdocs:devsop:commits)= +## Git commits + +Git commit messages are extremely important because they allow us to nicely track the complete development history of the project. +Here are some guidelines on writing good commit messages: + +- Each commit should ideally only address one issue. + It should be self-contained (should not group together lots of changes). + Tip: use `git add -p` to break your work down into logical, small commits). +- Write good commit messages. + Read [this post](https://chris.beams.io/posts/git-commit/) to see how to write meaningful, useful commit messages and why they are important. +- We strongly suggest using the [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. + In short: + + - Each commit is of the form `[optional scope]: description`, followed by the text body of the commit after a blank line, and then any optional references etc. as footer. + - The `type` can be one of: `fix`, `feat`, `build`, `chore`, `ci`, `docs`, `refactor`, `perf`, `test`, and so on depending on what the commit is doing. + - Any backwards incompatible, breaking change must be clearly noted in the commit using the `BREAKING CHANGE` phrase. + This corresponds to a major version update (as noted above in the versioning section). + +(devdocs:devsop:style:java)= +## Code style: Java + +TODO + +(devdocs:devsop:style:python)= +## Code style: Python + +- While Python 2 is still supported even though it is [no longer supported by the Python community](https://pythonclock.org), given that most Python modules (numpy/scipy/matplotlib/sphinx) have dropped support for this deprecated Python version, NeuroML will also drop support in the near future. + Therefore, we strongly suggest using Python 3. +- For Python repositories, please use [Black](https://black.readthedocs.io/) to format your code before committing and submitting a pull request. +- We also strongly suggest linting using [flake8](https://flake8.pycqa.org/). +- Please use [type hints](https://docs.python.org/3/library/typing.html?highlight=type%20hint) in your code and run [mypy](https://mypy.readthedocs.io/en/stable/) to test it for correctness. + You can see the [mypy cheatsheet](https://mypy.readthedocs.io/en/stable/cheat_sheet.html) to quickly see how to do this. + Since NeuroML is currently still supporting Python 2, we use the Python 2 style to maintain compatibility (this also works with Python 3). +- Deprecations should be clearly noted in the code, and in the commit message. + You may use the [Sphinx deprecated directive](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-deprecated) along with the Python [DeprecationWarning](https://docs.python.org/3/library/exceptions.html#DeprecationWarning), for example. + +(devdocs:devsop:docs)= +## Documentation + +All tools include their own documentation in their repositories. +Please feel free to improve this documentation and submit pull requests. + +When contributing fixes and enhancements, please remember to document your classes/functions and code in general. +Not only does this allow others to understand your code, it also allows us to auto-generate documentation using various tools. + +- For the Java repositories, please use the standard [Javadoc](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html) syntax. +- For the Python repositories, please document your code using the standard [Sphinx reStructuredText](https://www.sphinx-doc.org) system. + For functions and so on, you can use the provided [fields](https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html?#python-signatures). + +Where applicable, please add examples and so on to the software documentation to ensure that users can find the information quickly. +Additionally, please remember to consider if this primary NeuroML documentation here needs to be updated. + +Please use [Semantic Line Breaks](https://sembr.org/) wherever possible. + +(devdocs:devsop:testing)= +## Testing + +- Before submitting a pull request, please run the various tests to confirm your changes. + You can see how they are run in the various GitHub workflow files (in the `.github/workflows/` folder in each repository). + They will be run on all pull requests automatically so you can also verify your changes there. +- For a new feature addition, please remember to include a unit test. +- For a bug fix, please include a regression test. diff --git a/_sources/Devdocs/Devdocs.md b/_sources/Devdocs/Devdocs.md new file mode 100644 index 00000000..5486ea37 --- /dev/null +++ b/_sources/Devdocs/Devdocs.md @@ -0,0 +1,15 @@ +(devdocs:overview)= +# Overview + +This section will contain information for those who wish to **contribute to the development** of the NeuroML standard and associated tools. + +An overview of the NeuroML **release process** can be found {ref}`here `. + +The relationship of NeuroML to a number of other tools and standards in computational neuroscience, +and the practical steps taken thus far to ensure interoperability, can be found {ref}`here `. + +The following project Kanban boards are used to consolidate issues: + +- [NeuroML](https://github.com/orgs/NeuroML/projects/4/views/1): for all repositories under the NeuroML GitHub organization +- [LEMS](https://github.com/orgs/LEMS/projects/2/views/1): for all repositories under the LEMS GitHub organization +- [NeuralEnsemble](https://github.com/orgs/NeuralEnsemble/projects/1/views/1): for all NeuroML related repositories in the Neural Ensemble GitHub organization diff --git a/_sources/Devdocs/InteractionOtherBits.md b/_sources/Devdocs/InteractionOtherBits.md new file mode 100644 index 00000000..fbd777a3 --- /dev/null +++ b/_sources/Devdocs/InteractionOtherBits.md @@ -0,0 +1,40 @@ +(devdocs:interaction)= +# Interaction with other languages and standards + +```{admonition} Needs work +TODO: Add more information to each of these +``` + +(devdocs:interaction:pynn)= +## PyNN + +[https://github.com/NeuroML/NeuroML2/issues/73](https://github.com/NeuroML/NeuroML2/issues/73) + +(devdocs:interaction:sbml)= +## SBML + +[https://github.com/OpenSourceBrain/SBMLShowcase](https://github.com/OpenSourceBrain/SBMLShowcase) + + +(devdocs:interaction:sonata)= +## Sonata + +[https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1007696](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1007696) + + +(devdocs:interaction:nineml)= +## NineML & SpineML + +[https://github.com/OpenSourceBrain/NineMLShowcase](https://github.com/OpenSourceBrain/NineMLShowcase) + + +(devdocs:interaction:mdf)= +## ModECI MDF + +[http://www.modeci.org/](http://www.modeci.org/) + +(devdocs:interaction:swc)= +## SWC + +http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html +http://www.neuromorpho.org/myfaq.jsp diff --git a/_sources/Devdocs/ReleaseProcess.md b/_sources/Devdocs/ReleaseProcess.md new file mode 100644 index 00000000..db2f646c --- /dev/null +++ b/_sources/Devdocs/ReleaseProcess.md @@ -0,0 +1,41 @@ +(devdocs:release)= +# Release Process + +## Overview + +In general, work is carried out in the **development** branches of the [main NeuroML repositories](https://github.com/NeuroML/.github/blob/main/testsheet/README.md) +and these are merged to **master** branches on a new major release, e.g. move from NeuroML v2.1 to v2.2. + +A single page showing the **status of the automated test** as well as any **open Pull Requests** on all of the core NeuroML repositories can be found [here](https://github.com/NeuroML/.github/blob/main/testsheet/README.md). + +## Steps for new major release + +These are the steps required for a new release of the NeuroML development tools. + +| Task | Version this was last done | +| --- | --- | +| Commit final stable work in development branches | v2.3 | +| Make releases (not just tag - generates DOI) previous development versions of individual repos | v2.3 | +| Increment all version numbers - to distinguish release from previous development version | v2.3 | +| Test all development branches - rerun GitHub Actions at least once | v2.3 | +| Recheck all READMEs & docs | v2.3 | +| Run & check [test.py](https://github.com/NeuroML/NeuroML2/blob/master/test.py) in NeuroML2 repo | v2.3 | +| Check through issues for closed & easily closable ones | v2.3 | +| Update version in {ref}`documentation pages ` | v2.3 | +| Update [HISTORY.md](https://github.com/NeuroML/NeuroML2/blob/master/HISTORY.md) in NeuroML2 | v2.3 | +| pylems: Update README; Merge to master; Tag release; Release to pip | v2.3 | +| libNeuroML: Update README; Retest; Merge to master; Tag release; Release to pip; Check [installation docs](https://libneuroml.readthedocs.org/en/latest/install.html) | v2.3 | +| pyNeuroML: Update Readme; Tag release; Release to pip | v2.3 | +| NeuroMLlite: Update Readme; Tag release; Release to pip | v2.3 | +| Java repositories ({ref}`jNeuroML `, org.neuroml.* etc.): Merge development to master; Tag releases | v2.3 | +| Rebuild jNeuroML & commit to [jNeuroMLJar](https://sourceforge.net/p/neuroml/code/HEAD/tree/jNeuroMLJar/) and use latest for [jNeuroML for OMV](https://github.com/OpenSourceBrain/osb-model-validation/blob/master/omv/engines/getjnml.py#L8) | v2.3 | +| Add new binary release on [https://github.com/NeuroML/jNeuroML/releases](https://github.com/NeuroML/jNeuroML/releases) | v2.3 | +| Update version used in [neuroConstruct](https://github.com/NeuralEnsemble/neuroConstruct) | v2.3 | +| Update docs on [http://docs.neuroml.org](https://docs.neuroml.org) | v2.3 | +| Update version on [COMBINE website](https://github.com/combine-org/combine-org.github.io/blob/master/content/authors/NeuroML/_index.md) | v2.2 | +| ANNOUNCE (mailing list, Twitter) | v2.2 | +| Increment version numbers in all development branches | v2.3 | +| DOI on [Zenodo](https://doi.org/10.5281/zenodo.593108) | v2.3 | +| Update NeuroML [milestones](https://github.com/NeuroML/NeuroML2/milestones) | v2.2 | +| New release of [neuroConstruct](https://github.com/NeuralEnsemble/neuroConstruct/releases) | v2.3 | +| Test toolchain on Windows... | v2.0 | diff --git a/_sources/Devdocs/UpdatingStandard.md b/_sources/Devdocs/UpdatingStandard.md new file mode 100644 index 00000000..820ad2d9 --- /dev/null +++ b/_sources/Devdocs/UpdatingStandard.md @@ -0,0 +1,74 @@ +(devdocs:updating_standard)= +# Making changes to the NeuroML standard + +The NeuroML standard is stored in two sets of files, each serving a specific purpose: + +- the NeuroML [XML Schema Definition](https://en.wikipedia.org/wiki/XML_Schema_(W3C)) (XSD) file: this specifies the structure of a valid NeuroML XML file: what XML tags may be used and the how they are related +- the NeuroML [LEMS](http://lems.github.io/LEMS/) ComponentType definition XML files: these include the definitions of the NeuroML standard ComponentTypes in LEMS constructs, which include the mathematical details underlying these ComponentTypes + +These files are housed in the [NeuroML](https://github.com/NeuroML/NeuroML2/) repository. + +The XSD schema file is used to validate NeuroML XML files, as shown in the {ref}`page on validating NeuroML files `. +Further, the NeuroML Python model in {ref}`libNeuroML ` is also generated from the XSD file using the [generateDS](http://www.davekuhlman.org/generateDS.html) utility. + +The LEMS ComponentType definition XML files are also used for a series of additional validation tests, and since they include the details of the underlying dynamics for all ComponentTypes, they are also used for the simulation of NeuroML models either using the reference LEMS interpreter, {ref}`jLEMS `, or through automated code generation for supported simulation platforms (via {ref}`jNeuroML `). +Additionally, the LEMS definition files are also used the generate the {ref}`human readable schema documentation ` included in this documentation resource. + +The two sets of files are therefore, tightly coupled. +Any changes to the XSD file must also be followed by corresponding changes to the LEMS definition files. + +(devdocs:updating_standard:proc)= +## Procedure + +```{admonition} PR waiting +TODO: A pull request to include the `transfer_docs_to_xsd.py` script in the repository is in review here: https://github.com/NeuroML/NeuroML2/pull/172 +``` + +The suggested way of making changes to these files is via pull requests to the NeuroML repository which will undergo review by the NeuroML editorial board and the development team. +As noted in the {ref}`general contribution guidelines `, the `development` branch tracks the next release of the NeuroML standard. +So, all pull request must be made against the `development` branch. + +- New ComponentTypes, and their elements (parameters, variables etc.) that are added in the LEMS definition XML files should be properly documented. +- After both sets of files have been modified, please run the `transfer_docs_to_xsd.py` script in the `scripts` folder to copy documentation over from the XML files to the XSD schema file. This script will also run basic sanity checks to ensure that all ComponentTypes in the LEMS XML definition files are represented in the XSD schema file and vice-versa. +- Please run `xmllint` on the files to ensure they are formatted correctly. +- Please make individual commits for changes to the XSD file, and the XML files. This ensures that their change history is clearly maintained. + +(devdocs:updating_standard:schema_docs)= +## Regenerating schema documentation + +Once the pull request has been merged in the NeuroML repository, the {ref}`human readable schema documentation included in this documentation resource ` must be updated. +This is done by running the [generate-jupyter-ast.py](https://github.com/NeuroML/Documentation/blob/master/scripts/schemas/generate-jupyter-ast.py) script included in the [documentation source repository](https://github.com/NeuroML/Documentation). +This will read the LEMS XML definition files and regenerate the corresponding documentation pages. +A pull request can then be opened with the updated pages. + + + +(devdocs:updating_standard:org_neuroml_model)= +## Updating the Java API: org.neuroml.model + +TODO: Document what needs to be done for https://github.com/NeuroML/org.neuroml.model + + + +(devdocs:updating_standard:libneuroml)= +## Updating the Python API: libNeuroML + +```{admonition} PR waiting +TODO: A pull request to include the `regenerate-nml.sh` script in the repository is in review here: https://github.com/NeuralEnsemble/libNeuroML/pull/110 +``` + +Any changes to the XSD schema file require regeneration of the [Python object model in libNeuroML](https://github.com/NeuralEnsemble/libNeuroML/blob/development/neuroml/nml/nml.py): + +- copy over the updated XSD schema file to the `neuroml/nml/` directory in the `development` branch +- commit the new XSD file +- run the `regenerate-nml.sh` script to regenerate and reformat `nml.py` +- build and install libNeuroML into a new virtual environment +- run all tests using `pytest` +- run all examples and ensure that they run correctly (please see the [GitHub actions workflow](https://github.com/NeuralEnsemble/libNeuroML/blob/master/.github/workflows/ci.yml#L44) for more information) +- if all checks pass successfully, a pull request can be opened + +(devdocs:updating_standard:c_api)= +## Updating the C++ API + +TODO: Document what needs to be done for https://github.com/NeuroML/NeuroML_API/ + diff --git a/_sources/Events/2012-Edinburgh.md b/_sources/Events/2012-Edinburgh.md new file mode 100644 index 00000000..0042916d --- /dev/null +++ b/_sources/Events/2012-Edinburgh.md @@ -0,0 +1,304 @@ +(neuromlevents:2012edinburgh)= +# March 2012: Fourth NeuroML Development Workshop + +Convergence in Computational Neuroscience 2012 +Joint BrainScaleS CodeJam/NeuroML workshop, Edinburgh, 12-16th March + +The NeuroML Development Workshops and the [BrainScaleS](http://brainscales.kip.uni-heidelberg.de/) (previously FACETS) [CodeJams](http://neuralensemble.org/meetings.html) have been two important initiatives in recent years for developers of tools in computational and systems neuroscience to present their latest work, exchange ideas and work at achieving interoperability between software applications for investigating brain function. +This year these groups held a joint workshop (Convergence in Computational Neuroscience) on March 12th-16th in the Informatics Forum in Edinburgh, UK. +The meeting was held at the [Informatics Forum](https://www.ed.ac.uk/informatics/about/location/forum) in Edinburgh, UK, from 12th to 16th March 2012. + + +## Meeting report +Note: details of the meeting activities from Wednesday 14th to Friday 16th are available on the [NeuralEnsemble.org webpage](http://neuralensemble.org/meetings/CodeJam5/). + + +### Monday 12th March: NeuroML Development Workshop Day 1 + +#### Morning session: Current state of NeuroML 2 development & relationship to other initiatives +Chair: Andrew Davison + +```{list-table} +:header-rows: 1 +:widths: 10, 70, 20 + +* - Time + - Session + - Speaker + + +* - 09:00 + - **Welcome & goals of meeting** + + Angus welcomed attendees, thanking in particular out local organisers at University of Edinburgh, Mike Hull and Mika Pelko! + - Angus Silver + + +* - 09:05 + - **Update on latest developments in NeuroML 2/LEMS ([PPT](https://docs.neuroml.org/_static/NeuroML2012/PGleeson_NeuroMLIntro2012.ppt))** + + Padraig presented an introduction to NeuroML, starting with an overview of the modular nature of NeuroML v1.x, advantages of the use of XML, examples of neuronal models in NeuroML, current tools which support the language, (including the recently added NeuroMorpho.org and Channelpedia). + + The requirements for v2.0 were presented. Explicit definitions of model component behaviour allows description of the dynamics of model components in a simulator independent, machine readable way. The relationship between LEMS and NeuroML2 was discussed. A short overview of NeuroML 2.0 was given including dimensions/units. Example of adaptive exponential integrate and cell network was presented. An overview of libNeuroML was given. Export to NEURON, neuroConstruct, interaction with SBML was shown. + - Padraig Gleeson + +* - 09:30 + - **Introduction to NineML & libNineML ([PDF](https://docs.neuroml.org/_static/NeuroML2012/MHull_NineML.pdf))** + + Mike gave an introduction to the NineML object model and libNineML. The INCF Task Force in Multiscale Modelling created the language, consisting of an Abstraction Layer and User Layer. Mike's presentation focused on the abstraction layer which contains many terms for the object model. Core object in the Abstraction layer were presented: ComponentClass, Interface with Parameters, Ports (AnalogPorts, EventPorts and Reduce Ports), Dynamics with StateVariables and a Regime Transition Graph (with Transitions, StateAssignments, Aliases). + + libNineML (in Python) loads and saves models from/to XML to/from Python that helps with code generation, turns models into NEST, NEURON and PyNN. + + - Mike Hull + +* - 10:00 + - **The COMBINE Initiative ([PDF](https://docs.neuroml.org/_static/NeuroML2012/NleNovere_NeuroML-COMBINE.pdf))** + + Nicolas presented the Combine Initiative: Standards for describing the whole life-cycle of modelling. Different communities favour different types of models that are more suited for their domain. Current standardisation efforts depend on the initial people, individual funding structure, IP issues. Specifications, API's, test-suites, etc. really need industry-grade support which is not compatible with standard academic usages and possibilities. + + The vision of COMBINE is to pave the space of model descriptions with coordination of standard development (without interference with the development). There are criteria for inclusion in the core COMBINE standards: new standards must be different from those already included, described in technical specification documents, free, open, developed and used by more than one team, democratically elected members, mature software support including API, and must be actively developed. + + COMBINE organises joint meetings replacing standards specific ones (e.g. SBML Hackathon). Next COMBINE meeting is in Toronto in August. HARMONY for hacking will be in Maastricht in May. + - Nicolas le Novere + +* - 10:30 + - **Coffee** + - + +* - 11:00 + - **The International Neuroinformatics Coordinating Facility** + + Sean presented the motivation for, current structure and the aims of the INCF. The goal of neuroscience is to understand the brain. We're at a crisis point in understanding disorders. Big Pharma is pulling out of neuroscience due to the high cost and risk of understanding these disorders. Past centuries have focused on obtaining observations. More recently, models were used to understand these observations. Today we have eScience as a new way of handling large-scale data, modelling, simulations, linking data, etc. One of the INCF's goals is to transform neuroscience into an eScience from level of molecules to clinic. + + Integration of databases is a goal, which requires standardized data formats. There are 16 member countries in INCF. He gave an introduction to the 4 programs from the past few years: Digital Brain Atlasing, Multi-Scale Modeling, Ontologies of Neural Structures and Standards for Datasharing. + + He discussed future plans for the INCF "Cyberinfrastructure", including a discussion of the planned INCF cloud "Dropbox" for data which could include metadata tags enabling global search. + + - Sean Hill + +* - 11:30 + - **Collaborative Modelling Repository update** + + Padraig presented the initial work towards an open source, collaborative repository for NeuroML models, the Open Source Brain project. A preliminary version of this is avaliable here. It will be based on a version control repository (initially Mercurial) storing the model files. It will have automatic generation of online documentation of the models from ChannelML, MorphML, etc. Connectivity matrices for network connections, etc. can be generated for models which are stored in neuroConstruct format. NeuroLex IDs can be used to identify cells and channels to other resources. Feedback on the initial implementation was welcomed. + + - Padraig Gleeson + +* - 12:00 + - **Open discussion on model specification initiatives** + + Differences were pointed out between INCF and COMBINE approaches to standards development. IEEE provides an infrastructure for review, etc. Nicolas discussed the burdens of obtaining "official" standards board recognition. Many of the COMBINE procedures imitate W3C procedures. A good standard is one that works. COMBINE criteria don't say anything about the standard document itself. + - + +* - 13:00 + - **Lunch** + - +``` + +#### Afternoon session: Specification of detailed biophysical components in NeuroML 2/LEMS +Chair: Sharon Crook + +```{list-table} +:header-rows: 1 +:widths: 10, 70, 20 + +* - Time + - Session + - Speaker + + +* - 14:00 + - **Representing channels, synapses & conductance based models ([PDF](https://docs.neuroml.org/_static/NeuroML2012/RCannon_ModellingIonChannels.pdf))** + + Robert gave a presentation on ways to represent synapses and conductances. He defined the Nernst equation with XML based on Hille's description. It is still not clear how some things should be done, in particular how to handle dimensions and units. Currently, dimensions are defined and then assertions about relationships among dimensions can be made. Units are not defined until NeuroML is written (with numerical values, e.g. -70mV). There was some discussion of how dimensions should be defined. Physicists solved this problem by developing SI units. Both space and no space between values and units are allowed in LEMS. There was some discussion of how events can be handled in LEMS. + - Robert Cannon + + +* - 14:20 + - **Experiences with using NeuroML 2** + + Avrama gave a brief report of her hands on experience with using NeuroML 2. She has a medium spiny projection neuron model which she's translating to GENESIS. She didn't want to use a GUI unless absolutely necessary and has been manually editing the XML. Many of the (non calcium dependent) channels have already been converted to NeuroML 2. She can only run single compartment versions of her model since LEMS doesn't yet support multi compartmental models. She has produced some some multi segment morphologies in NML2, even though these can't be used in LEMS based simulations yet. She requires a way to specify distance from the soma. Another difficulty is not being able to define a template (dendritic) subbranch and add it multiple times to the cell. She will add spines later. Calcium dependent channels are a work in progress in NeuroML v2.0, but some useful simulations have already been done with her developing model. + + - Avrama Blackwell + +* - 14:40 + - **Implementing cerebellar models in PyNEURON, neuroConstruct & NeuroML** + + Sergio is developing cerebellar models (Golgi cells and granular cells) in a network of granule layer. Solinas S, Nieus T and D`Angelo E (2010) A realistic large-scale model of the cerebellum granular layer predicts circuit spatio-temporal filtering properties. Frontiers in Cellular Neuroscience ([link](http://www.frontiersin.org/Cellular_Neuroscience/10.3389/fncel.2010.00012/abstract)) gives an overview of the network. There were improvements made to the model in 2011 and it was translated to Python Neuron for parallel simulation on cluster. Added gap junctions, more realistic inputs. Python eased improvements to the model. + + - Sergio Solinas + +* - 15:00 + - **Large scale cortical models for studying LFPs ([PPT](https://docs.neuroml.org/_static/NeuroML2012/RTomsett_LargeScaleCorticalModel.ppt))** + + Richard presented his work on developing large scale cortical models for studying Local Field Potentials. What network properties cause pathological dynamics? Much data comes from electrodes in vitro. Gaute Einevol's work looks at how dendritic structure affects the field potentials in a network (Linden et al Neuron 2010). Richard focused on Bush and Sejnowski J Neurosci Methods 1993 method to reduce model and see what the LFP looks like (and compared to Linden data). Then since it looked pretty good he created a network of these reduced models for simulation and analysis. Then looked at results from Utah array in Matlab. Next he'll add Gaussian connectivity and some patches and long range connections. + + - Richard Tomsett + + +* - 15:15 + - **Coffee** + - + +* - 15:30 + - **Break out sessions** + + - Channel and synapse specifications + - Proposed structure for abstract neuron model hierarchy + + - + +* - 17:30 + - **Reconvene and presentated discussions** + - + +* - 18:00 + - **Close** + - +``` + +### Tuesday 13th March: NeuroML Development Workshop Day 2 +#### Morning session: Representing morphologies/support for detailed neuronal simulators/relationship to connectomics initiatives +Chair: Michael Hines + +```{list-table} +:header-rows: 1 +:widths: 10, 70, 20 + +* - Time + - Session + - Speaker + + +* - 09:00 + - **The Neural Tissue Simulator([PDF](https://docs.neuroml.org/_static/NeuroML2012/JKozloski_NeuroML_workshop_2012.pdf))** + + James presented his work on the Neural Tissue Simulator, much of which was contained in the recent publication: Kozloski J and Wagner J (2011) An ultrascalable solution to large-scale neural tissue simulation. Frontiers in Neuroinformatics. 5:15. ([link](http://www.frontiersin.org/neuroinformatics/10.3389/fninf.2011.00015/abstract)). + + The key goals of this work are: to develop a simulator capable of testing mappings to various machine architectures, both parallel and multithreaded; to develop support for high level, abstract model definitions and simulation specifications; and to create an extensible simulator, able to map arbitrary, domain level models directly to a variety of data arrangements and computational implementations. + + James discussed the process of defining the model (using the Model Definition & Graph Specification Languages), how the model elements are partitioned on the computing resources, and how these elements communicate during simulation to solve the model equations. He discussed the specific case of simulating cortical columns when synapses were determined through contact detection algorithms. He also presented some results for how the simulator scales for larger networks. The Neural Tissue Simulator is not currently publicly available, but James is keen to make it available, and to build a community of users. NeuroML support is also planned + + - James Kozloski + +* - 09:30 + - **The Blue Brain Project** + + Eilif presented an overview of the Blue Brain Project's efforts to reverse engineer a P14 Rat non-barrel somatosensory cortical column. Based on a database of anatomical reconstructions, electrophysiology, etc. they will fill the cortical column with cells based on known location, probability distributions. Morphologies for those classes of cells are taken from library of cells called a collage with some rules about how they fit in based on constraints from reconstructions. Some of these cells have been "repaired" due to axon cuts in reconstructions. + + Functional circuits are also based on biological data. Electrical behaviors are based on classifications based on firing patterns observed in experiments. This is combinatorial since each morphological class has a number of possible firing patterns. They use genetic algorithm to adjust parameters which are set up based on what is known (gene expression, etc). Channelome project uses cell culture and automated patch clamp by robot and then automated model fitting for data that are then posted to Channelpedia. Channels there are available in ChannelML. Synaptic parameterization and validation for functional synapses are also based on database of recorded synaptic properties. + + In silico model is compared to in vitro using same protocols as experiments. There was a standards and interoperability discussion: they are mostly using custom formats other than what they use with NEURON. Eilif welcomed greater support for more widely used standards. + + - Eilif Muller + +* - 10:00 + - **Tools for the dense reconstruction of neuronal circuits** + + Moritz gave an overview of his recent work with Winfried Denk and Frank Briggman, which is continuing in his own lab. They have used Serial Block-Face Electron Microscopy (SBEM), to investigate the connectivity in blocks of neuronal tissue, which has been the subject of a number of recent publications, e.g. K.L. Briggman, Helmstaedter, M. and W. Denk, Wiring specificity in the direction-selectivity circuit of the mammalian retina. Nature 471, 183-188, 2011. ([link](http://www.nature.com/nature/journal/v471/n7337/full/nature09818.html)). + + He also discussed the application [KNOSSOS](http://www.knossostool.org/) which was developed to facilitate the reconstruction of neuronal morphologies from such data. While this tool uses a proprietary format for storing morphologies, it is open source and Mortiz was keen to integrate the application with other tools using NeuroML. + + - Moritz Helmstaedter + +* - 10:30 + - **Coffee** + - + +* - 11:00 + - **The OpenWorm project: Using NeuroML in a highly detailed model of C. elegans ([PPT](https://docs.neuroml.org/_static/NeuroML2012/Open_Worm_03-13-12.ppt))** + + Stephen presented the OpenWorm project. This ambitious project aims to build an in silico model of C. elegans. This well studied system with ~1000 cells and 302 identified neurons is an ideal system with which to attempt a full simulation of a living organism down to cellular scale. Many different approaches are being take in the project at the moment, including investigatin Smoothed Particle Hydrodynamics (SHP) to allow simulation of the interaction of the worm with its environment, and creating a new parallel (GPU based) simulator in Java which will support physical and electrical simulations. Full reconstructions of all of the cells are available in 3D and those of the neurons have been converted to NeuroML, which will form the basis of a simulation of the worm's nervous system. + + One of the concrete outcomes of code sprinting work on the fringes of the NeuroML/CodeJam meeting was the updated OpenWorm Browser, where the full cellular structure of the worm can be browsed in 3D. + + - Stephen Larson + +* - 11:30 + - **Open discussion on tool support for large scale neural simulations** + - + +* - 13:00 + - **Lunch (provided)** + - +``` + +#### Afternoon session: Best practices when implementing support for NeuroML in simulators +Chair: Avrama Blackwell + +```{list-table} +:header-rows: 1 +:widths: 10, 70, 20 + +* - Time + - Session + - Speaker + + +* - 14:00 + - **Introduction to SED-ML ([PDF](https://docs.neuroml.org/_static/NeuroML2012/DWaltemath_sed-ml_edinburgh2012_.pdf))** + + Dagmar gave an overview of the motivation behind the development of SED-ML, the Simulation Experiment Description language , the current status of the specification, and some of the uses it has been put to so far. It compliments a model description in SBML or NeuroML and allow specification of the simulation algorithm used to run the model, any changes made to the parameters specified in the model description, the simulation duration, what variables were saved during the simulation, and how that data was processed. + + In SED-ML you can define a uniform time course with an initial time and start and end time. This needs to be expanded to other possible time courses. Multiple tasks (simulations) can be defined. For example, run the original database model and the changed model. Output can be set up as 2D or 3D plots or a datatable. SED-ML has an elected board of editors. Contribution to SED-ML is encouraged. Sourceforge can be used for feature requests and this will move forward as people contribute. + + - Dagmar Waltemath + + +* - 14:20 + - **Introduction to CNO: an ontology for annotating computational neuroscience models ([PDF](https://docs.neuroml.org/_static/NeuroML2012/YleFranc_CNO.pdf))** + + Yann presented an introduction to CNO: an ontology for annotating computational neuroscience models. All classes must have a unique identifier, a label (name) and a human-readable definition. Relationships among classes are specified with relations. Examples are subsumption relations, associative relations, etc. We then can associate this semantic information with parts of XML files. + + - Yann le Franc + +* - 14:40 + - **NeuroLex & NIF update ([PPT](https://docs.neuroml.org/_static/NeuroML2012/NeuroLexNIFupdate_3-13-12.ppt))** + + Stephen gave us an update on NeuroLex and the Neuroscience Information Framework (NIF). We need for an online parts list for the brain. NeuroLex is built on Wiki technology with extra functionality to create structured knowledge where anyone can create or edit. It currently as about 18,000 concepts. NIF funds curators from NIH money and also looks for volunteers. In the future they want to dominate Google searches with NeuroLex terms. Looking to Yelp for how they display info including images and related queries and such. Some place for community comments. Another goal is to expose high quality linked data with example of an open linked data graph. + + - Stephen Larson + +* - 15:00 + - **libSBML and SBML L3 ([PDF](https://docs.neuroml.org/_static/NeuroML2012/SKeating_libsbml-and-sbml.pdf))** + + Sarah gave a brief overview of libSBML and SBML Level 3. libSBML, which provides an API for creating, editing and saving SBML in many languages (e.g. C++, Python, Java, Ruby, Perl) has been instrumental in the growth of the number of applications supporting SBML. + + SBML Level 3 has a modular architecture, featuring a core specification (roughly in line with previous SBML releases) and a number of specialist packages, which applications can choose to support or not. Examples of these packages incluse layout for storing the spatial topology of a model's network diagram, comp for defining how a model is composed from other models and spatial for describing models that involve a spatial component. libSBML already has a generic framework to support extensions for generic packages. + + - Sarah Keating + + +* - 15:15 + - **Coffee** + - + +* - 15:30 + - **Break out sessions** + + - How best to map generic model descriptions to a given simulator + - Support for morphologies + + - + +* - 17:30 + - **Reconvene and presentated discussions** + - + +* - 18:00 + - **Close of meeting** + - +``` + +### Wednesday 14th March--Friday 16th March + +Full details of the meetings from Wed-Fri are available on the [NeuralEnsemble.org webpage](http://neuralensemble.org/meetings/CodeJam5/) for the meeting. + + +## Funding + +The NeuroML part of this workshop was made possible with funding from: + +- The National Institutes of Health +- Wellcome +- The UK Neuroinformatics Node +- The International Neuroinformatics Co-ordinating Facility (INCF) diff --git a/_sources/Events/202103-Harmony.md b/_sources/Events/202103-Harmony.md new file mode 100644 index 00000000..db4631b3 --- /dev/null +++ b/_sources/Events/202103-Harmony.md @@ -0,0 +1,49 @@ +(neuromlevents:202103harmony)= +# March 2021: NeuroML hackathon at HARMONY 2021 + +```{admonition} Registration for the COMBINE initiative's HARMONY 2021 meeting is free. +:class: tip +Register for the COMBINE: HARMONY 2021 meeting [here](http://co.mbine.org/events/HARMONY_2021). +Registration is free. +``` + +We will be running 3 online NeuroML hackathon sessions during the upcoming [COMBINE: HARMONY 2021](http://co.mbine.org/events/HARMONY_2021) meeting on 23-25th March. +The general theme of the sessions will be: **learn to build, visualise, analyse and simulate your models using NeuroML**. + +(neuromlevents:202103harmony:why)= +## Why take part? + +These hackathons will give members of the neuroscience community the chance to: + +- Get high level introductions to the NeuroML language and tool chain +- Meet the NeuroML core development team and editors +- Find out the latest information on which simulators/applications support NeuroML +- Open, discuss and work on issues related to converting your model to NeuroML, or supporting NeuroML in your simulator +- Learn how to share your models with the community + +(neuromlevents:202103harmony:when)= +## Times and dates + +All sessions will be online and take place over 3 hours (9am-noon Pacific; 12-3pm EST time; 4-7pm UK/UTC; 5-8pm CET, 9:30pm-12:30am IST; note non-standard US/EU time differences that week). +The broad focus of each of the sessions (dependent on interests of attendees) is: + +- Tues 23rd March: Introduction to NeuroML, general questions about usage +- Wed 24th March: Detailed cell/conductance based models (e.g. converting channels to NeuroML) +- Thus 25th March: Abstract/point neuron networks including PyNN interactions + +(neuromlevents:202103harmony:registration)= +## Registration + +To take part in the hackathon, please register [here](http://co.mbine.org/events/HARMONY_2021) for the HARMONY meeting (registration is free). +You will get sent details to access the [agenda](https://harmony2021.sched.com), which will have links to the Zoom sessions for each of the days. + +(neuromlevents:202103harmony:prepare)= +## Open an issue beforehand! +While it will be possible to raise and discuss new issues at the hackathons, it will be easier to manage and plan work/discussions if you open an issue with a description of the problem you are trying to address at: [https://github.com/NeuroML/NeuroML2/issues](https://github.com/NeuroML/NeuroML2/issues). + +(neuromlevents:202103harmony:slack)= +## Slack +To aid communication with the community during (and after) the meeting, we have a **Slack channel** for NeuroML related discussions. +Please contact [Padraig Gleeson](mailto:p_DOT_gleeson_AT_ucl.ac.uk) for an invite. + +We look forward to working with the community to drive further uptake of NeuroML compliant models and tools! diff --git a/_sources/Events/202107-CNS2021.md b/_sources/Events/202107-CNS2021.md new file mode 100644 index 00000000..3bed99aa --- /dev/null +++ b/_sources/Events/202107-CNS2021.md @@ -0,0 +1,48 @@ +(neuromlevents:202107cns2021)= +# July 2021: NeuroML tutorial at CNS*2021 + +```{admonition} Register for the 30th Annual meeting of the Organization for Computational Neurosciences (OCNS). +:class: tip +Register for the CNS*2021 [here](http://www.cnsorg.org/cns-2021). +``` + +We will be running a half day tutorial at the 30th annual meeting of the Organization for Computational Neurosciences (OCNS): [CNS*2021](https://www.cnsorg.org/cns-2021). + +The goal of the tutorial is to teach users to: **build, visualise, analyse and simulate models using NeuroML**. + +(neuromlevents:202107cns2021:why)= +## Why take part? + +This tutorial is aimed at new and current NeuroML users. We will start with a quick introduction to the NeuroML standard and the associated software ecosystem, after which we will proceed to conduct hands-on sessions to show how one can build computational models with NeuroML. + +(neuromlevents:202107cns2021:when)= +## Times and dates + +- [Friday 2nd July 1500UTC](https://www.timeanddate.com/worldclock/fixedtime.html?msg=NeuroML+tutorial+at+CNS%2A2021&iso=20210702T11&p1=179&ah=3). + +(neuromlevents:202107cns2021:registration)= +## Registration + +To take part in the tutorial, please register [here](https://www.cnsorg.org/cns-2021) for the CNS*2021 meeting. + +(neuromlevents:202107cns2021:prepare)= +## Pre-requisites + +The sessions will make use of the NeuroML Python tools. +Please follow the documentation to install them on your system if you wish to use them locally: + +- {ref}`PyNeuroML ` +- {ref}`libNeuroML ` + +You can also use the interactive Jupyter notebooks from the documentation if you prefer ([example](https://docs.neuroml.org/Userdocs/NML2_examples/SingleNeuron.html)). These can be run on Binder and Google Collab in your web browser and do not require you to install anything locally on your computer. + + +(neuromlevents:202107cns2021:slack)= +## Slack + +To aid communication with the community during (and after) the meeting, we have a **Slack channel** for NeuroML related discussions. +Please contact [Padraig Gleeson](mailto:p_DOT_gleeson_AT_ucl.ac.uk) for an invite. + +You can also contact the NeuroML community using one of our other {ref}`channels `. + +We look forward to working with the community to drive further uptake of NeuroML compliant models and tools! diff --git a/_sources/Events/202108-INCF-Training-Week.md b/_sources/Events/202108-INCF-Training-Week.md new file mode 100644 index 00000000..a6180090 --- /dev/null +++ b/_sources/Events/202108-INCF-Training-Week.md @@ -0,0 +1,41 @@ +(neuromlevents:202108incf)= +# August 2021: NeuroML tutorial at INCF Training Weeks + +A NeuroML tutorial will be held at the [Virtual INCF Neuroinformatics Training Weeks 2021](https://www.incf.org/virtual-incf-neuroinformatics-training-week-2021). + +This tutorial is intended for members of the research community interested in learning more about how NeuroML and its related technologies facilitates the standardization, sharing, and collaborative development of models. + +(neuromlevents:202108incf:when)= +## Times and dates + +This tutorial will be offered twice during the Neuroinformatics Training Week: session 1 is targeted to participants residing in Europe, Africa, and the Americas while session 2 is targeted to participants residing in Asia and Australia. + +Session 1: +- Dates: 23 Aug 2021 +- Time: : 11:00-15:00 EDT / 17:00-21:00 CEST + +Session 2 +- Dates: 26 Aug 2021 +- Time: 09:00-13:00 CEST / 16:00-20:00 JST / 17:00-21:00 AEST + +(neuromlevents:202108incf:who)= +## Target audience + +Anyone who is already familiar with computational modelling, but is keen to standardise, share and collaboratively develop their models. + +(neuromlevents:202108incf:agenda)= +## Agenda + +### Part 1: Introduction to NeuroML + +- Overview of NeuroML +- Introduce the NeuroML tool chain +- Introduce main documentation +- Related technologies and initiatives + +### Part 2: Hands on demonstrations of building and using NeuroML models + +- Izhikevich neuron hands on tutorial +- Spiking neuron network tutorial +- Single compartment HH neuron tutorial +- Multi compartmental HH neuron tutorial diff --git a/_sources/Events/202109-COMBINE.md b/_sources/Events/202109-COMBINE.md new file mode 100644 index 00000000..91fcf820 --- /dev/null +++ b/_sources/Events/202109-COMBINE.md @@ -0,0 +1,29 @@ +(neuromlevents:202109combine)= +# October 2021: NeuroML development workshop at COMBINE meeting + +```{admonition} Registration for the COMBINE 2021 meeting is free. +:class: tip +Register for the COMBINE 2021 meeting [here](https://combine-org.github.io/events/). +Registration is free. +``` + +A NeuroML development workshop will be held as part of the [annual COMBINE meeting in October 2021](https://combine-org.github.io/events/). + +The general theme of the workshop is to discuss the current status of the NeuroML standard and the complete software ecosystem, and future development plans. + +(neuromlevents:202109combine:when)= +## Times and dates + +- 13 October 2021 +- 8-11am PDT/11-2pm EST/4-7pm UK/5-8pm CET/8:30-11:30 IST + + +(neuromlevents:202109combine:who)= +## Target audience +Everyone that is involved/interested in developing tools that use/integrate with NeuroML is encouraged to join. + +Please register for the COMBINE meeting (free of charge) to receive access to the complete schedule of the meeting, including links to the various virtual meetings/sessions. + +## Agenda/minutes + +The agenda/minutes for the meeting can be found [here](https://docs.google.com/document/d/1rZp6fggUe1vlo5fYK-CiUP__fdJV8xYg-wrkpIp0dHk/edit). diff --git a/_sources/Events/202204-Harmony.md b/_sources/Events/202204-Harmony.md new file mode 100644 index 00000000..2768bb36 --- /dev/null +++ b/_sources/Events/202204-Harmony.md @@ -0,0 +1,39 @@ +(neuromlevents:202104harmony)= +# April 2022: NeuroML development workshop at HARMONY 2022 + +```{admonition} Registration for the COMBINE initiative's HARMONY 2022 meeting is free. +:class: tip +Please register for the COMBINE HARMONY 2022 meeting [here](https://combine-org.github.io/events/) if you are coming to our NeuroML workshop. +Registration for HARMONY is free. +``` + +We will be running a NeuroML development workshop during the upcoming [COMBINE network's HARMONY 2022](https://combine-org.github.io/events/) meeting on Thus 28 April 2022. +This will be an opportunity for anyone interested in developing NeuroML or adding support for the format to their application talk about their work and hear about other developments. + +(neuromlevents:202104harmony:agenda)= +## Agenda + +The agenda for the meeting can be found [here](https://docs.google.com/document/d/1GOkmylIlLH3dbxB2Pmis7VxFPzipstLBdXn5uBu4rv8/edit). + +(neuromlevents:202104harmony:when)= +## Times and dates + +The workshop will take place on **Thus 28 April 2022** at 15:00-18:00 UTC ([converter](https://www.timeanddate.com/worldclock/converter.html?iso=20220427T150000&p1=136&p2=1440&p3=137&p4=179&p5=37&p6=176&p7=248)). + +(neuromlevents:202104harmony:registration)= +## Registration + +To take part in the workshop, please register [here](https://combine-org.github.io/events/) for the HARMONY meeting (registration is free). + +You will get sent details to access the HARMONY agenda, which will have links to the **Zoom session for the NeuroML workshop**. + +(neuromlevents:202104harmony:prepare)= +## Open an issue beforehand! +While it will be possible to raise and discuss new issues at the workshop, it will be easier to manage and plan work/discussions if you open an issue with a description of the problem you are trying to address at: [https://github.com/NeuroML/NeuroML2/issues](https://github.com/NeuroML/NeuroML2/issues). + +(neuromlevents:202104harmony:slack)= +## Slack +To aid communication with the community during (and after) the meeting, we have a **Slack channel** for NeuroML related discussions. +Please contact [Padraig Gleeson](mailto:p_DOT_gleeson_AT_ucl.ac.uk) for an invite. + +We look forward to working with the community to drive further uptake of NeuroML compliant models and tools! diff --git a/_sources/Events/20220630-CNS2022.md b/_sources/Events/20220630-CNS2022.md new file mode 100644 index 00000000..24d3a3e6 --- /dev/null +++ b/_sources/Events/20220630-CNS2022.md @@ -0,0 +1,43 @@ +(neuromlevents:202206cns)= +# June 2022: NeuroML tutorial at CNS*2022 satellite tutorials + +An online NeuroML tutorial will be held at the [CNS*2022 satellite tutorials](https://ocns.github.io/SoftwareWG/pages/software-wg-satellite-tutorials-at-cns-2022.html). +Registration for the satellite tutorials is free, but required. + +This tutorial is intended for members of the research community interested in learning more about how NeuroML and its related technologies facilitates the standardization, sharing, and collaborative development of models. + +(neuromlevents:202206cns:when)= +## Times and dates + +- Dates: June 30, 2022 +- Time: : [1400--1700 UTC](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20220630T14) + + +(neuromlevents:202206cns:who)= +## Target audience + +Anyone who is already familiar with computational modelling, but is keen to standardise, share and collaboratively develop their models. + +(neuromlevents:202206cns:where)= +## Where + +The tutorial be done online via Zoom and will make use of the [Open Source Brain v2](https://v2.opensourcebrain.org) integrated web research platform. + +Please register for the [CNS*2022 satellite tutorials](https://ocns.github.io/SoftwareWG/pages/software-wg-satellite-tutorials-at-cns-2022.html) to receive the Zoom links. + +(neuromlevents:202206cns:agenda)= +## Agenda + +### Part 1: Introduction to NeuroML + +- Overview of NeuroML +- Introduce the NeuroML tool chain +- Introduce main documentation +- Related technologies and initiatives + +### Part 2: Hands on demonstrations of building and using NeuroML models + +- Izhikevich neuron hands on tutorial +- Spiking neuron network tutorial +- Single compartment HH neuron tutorial +- Multi compartmental HH neuron tutorial diff --git a/_sources/Events/202404-Harmony.md b/_sources/Events/202404-Harmony.md new file mode 100644 index 00000000..aca24099 --- /dev/null +++ b/_sources/Events/202404-Harmony.md @@ -0,0 +1,42 @@ +(neuromlevents:202404harmony)= +# April 2024: NeuroML hackathon at HARMONY 2024 + +```{admonition} Registration for the COMBINE initiative's HARMONY 2024 meeting is free. +:class: tip +Please register for the COMBINE HARMONY 2024 meeting [here](https://co.mbine.org/author/harmony-2024/) if you are coming to our NeuroML workshop. +Registration for HARMONY is free. +``` + +We will be running a NeuroML workshop during the upcoming [COMBINE network's HARMONY 2024](https://co.mbine.org/author/harmony-2024/) meeting on Tues 9th April 2024 in London, entitled: + +**NeuroML hackathon: convert your neuron and network models to open, standardised, reusable formats** + +This will be an opportunity for developers of models in computational neuroscience to get an introduction to the aims and structure of NeuroML, a guide to the tools available for building/converting their models to NeuroML, and to receive hands on help with expressing their models (or other published models they are interested in) in NeuroML format, making them more open, accessible and reusable. + +(neuromlevents:202404harmony:agenda)= +## Agenda + +More details to follow + +(neuromlevents:202404harmony:when)= +## Times and dates + + +More details to follow + +(neuromlevents:202404harmony:registration)= +## Registration + +To take part in the workshop, please register [here](https://co.mbine.org/author/harmony-2024/) for the HARMONY meeting (registration is free). + + +(neuromlevents:202404harmony:prepare)= +## Open an issue beforehand! +While it will be possible to raise and discuss new issues at the workshop, it will be easier to manage and plan work/discussions if you open an issue with a description of the problem you are trying to address at: [https://github.com/NeuroML/NeuroML2/issues](https://github.com/NeuroML/NeuroML2/issues). + +(neuromlevents:202404harmony:slack)= +## Slack +To aid communication with the community during (and after) the meeting, we have a **Slack channel** for NeuroML related discussions. +Please contact [Padraig Gleeson](mailto:p_DOT_gleeson_AT_ucl.ac.uk) for an invite. + +We look forward to working with the community to drive further uptake of NeuroML compliant models and tools! diff --git a/_sources/Events/202407-CNS2024.md b/_sources/Events/202407-CNS2024.md new file mode 100644 index 00000000..d8769e8b --- /dev/null +++ b/_sources/Events/202407-CNS2024.md @@ -0,0 +1,65 @@ +(neuromlevents:202407cns)= +# July 2024: NeuroML tutorial at CNS 2024 + +```{admonition} Registration for the annual meeting of the Organisation of Computational Neuroscience, CNS 2024, is open. +:class: tip +Please register for the CNS 2024 [here](https://www.cnsorg.org/cns-2024-quick). +``` + + +We will be running a full day NeuroML tutorial during the [annual meeting of the Organisation of Computational Neuroscience, 2024](https://www.cnsorg.org/cns-2024-quick) meeting in Natal, Brazil from July 20--24. + +**Standardised, data-driven computational modelling with NeuroML using Open Source Brian** + +Data-driven models of neurons and circuits are important for understanding how the +properties of membrane conductances, synapses, dendrites and the anatomical connectivity +between neurons generate the complex dynamical behaviours of brain circuits in health and +disease. However, even though data and models are being made publicly available in recent +years and the use of standards such as [Neurodata Without Borders (NWB)](https://nwb.org) +and NeuroML to promote FAIR (Findable, Accessible, Interoperable +and Reusable) neuroscience is on the rise, development of data driven models remains +hampered by the difficulty of finding appropriate data and the inherent complexity involved in +their construction. + +The [Open Source Brain web platform (OSB)](https://opensourcebrain.org) brings together +data, accompanying analysis tools, and computational models in a single, scalable resource. +It indexes repositories from established sources such as the [DANDI data +archive](https://dandiarchive.org), the [ModelDB model sharing +archive](https://modeldb.science), and GitHub to provide easy access to a +plethora of experimental data and models, including +a large number standardised in NWB and NeuroML formats + +OSB also incorporates the NeuroML software ecosystem. NeuroML is an established +community standard and software ecosystem that enables the development of biophysically +detailed models using a declarative, simulator independent description. The software +ecosystem supports all steps of the model lifecycle and allows users to automatically +generate code and run their NeuroML models using a number of well established simulation +engines (NEURON/NetPyNE). + +Read the NeuroML pre-print here: https://www.biorxiv.org/content/10.1101/2023.12.07.570537v1 + +(neuromlevents:202407cns:agenda)= +## Agenda + +In this tutorial, attendees will learn about: + +- Finding data and models on OSB +- NeuroML and its software ecosystem +- Using NeuroML models on OSB +- Building and simulating new NeuroML models constrained by the data on OSB + +We will also provide assistance with advanced tasks, and discuss new features to further aid researchers. + + +(neuromlevents:202407cns:when)= +## Times and dates + +More details to follow + +(neuromlevents:202407cns:registration)= +## Registration + +To take part in the tutorial, please register [here](https://www.cnsorg.org/cns-2024-quick) for CNS 2024. + + +We look forward to working with the community to drive further uptake of NeuroML compliant models and tools! diff --git a/_sources/Events/PastEvents.md b/_sources/Events/PastEvents.md new file mode 100644 index 00000000..a62e5fe9 --- /dev/null +++ b/_sources/Events/PastEvents.md @@ -0,0 +1,6 @@ +(neuromlevents:past)= +# Past NeuroML Events + +A number of developer workshops and editorial board meetings have been held since 2008 to coordinate and promote the work of the NeuroML community. These are listed {ref}`here `. + +There has been significant NeuroML involvement also at the meetings organised by the Open Source Brain initiative. See [here](https://www.opensourcebrain.org/docs#Meetings) for more details. diff --git a/_sources/Landing.md b/_sources/Landing.md new file mode 100644 index 00000000..a801f16e --- /dev/null +++ b/_sources/Landing.md @@ -0,0 +1,99 @@ +(landing)= +# NeuroML + +*A model description language for computational neuroscience.* + + +```{admonition} Read the latest NeuroML preprint on bioRxiv +:class: attention +[The NeuroML ecosystem for standardized multi-scale modeling in neuroscience](https://www.biorxiv.org/content/10.1101/2023.12.07.570537v1) +``` + + + + + +
+ + +NeuroML is an {ref}`international, collaborative initiative ` to develop a language for describing detailed models of neural systems, which will serve as a standard data format for defining and exchanging descriptions of neuronal cell and network models. +NeuroML is: + +- modular +- standardised +- structured + +and this allows you to: + +- easily {ref}`build ` and {ref}`optimise ` detailed models of neural systems +- easily {ref}`validate ` your models +- easily {ref}`visualise ` your models +- easily {ref}`simulate ` your models using a variety of simulators +- easily {ref}`analyse ` your simulations + +all using a {ref}`well supported set of tools ` in the powerful [Python](https://www.python.org) programming language. + +In this documentation, you will find information on {ref}`using NeuroML `, {ref}`developing with NeuroML `, its {ref}`specification `, and the {ref}`community ` that maintains it. + +For any queries, please contact the NeuroML community using any of our {ref}`communication channels `. diff --git a/_sources/NeuroMLOrg/Board.md b/_sources/NeuroMLOrg/Board.md new file mode 100644 index 00000000..4027666a --- /dev/null +++ b/_sources/NeuroMLOrg/Board.md @@ -0,0 +1,141 @@ +(neuromlorg:board)= +# NeuroML Editorial Board + +An elected board of editors has been formed to manage the NeuroML specification development process. +The editorial board consists of five members, elected by the NeuroML community. +The editors are responsible for producing and maintaining the official documentation for the NeuroML language, and work in collaboration with the {ref}`Scientific Committee ` who provide oversight and guidance. + +Due to the close link between the development of NeuroML 2 and LEMS, this group is also responsible for producing a stable specification for the subset of LEMS used by NeuroML 2. + +## Current Editorial Board + +The five current members of the NeuroML Editorial Board are: + +- Salvador Dura-Bernal +- Padraig Gleeson +- Boris Marin +- Ankur Sinha +- Sotirios Panagiotou + +Padraig Gleeson, Boris Marin and Sotirios Panagiotou were elected for three year terms in 2022 (2023--2025) and Salvador Dura-Bernal and Ankur Sinha were elected for three year terms in 2021 (2022--2024). + +% To force a new line in markdown, end the line with two or more spaces, so do not strip these. + +
+
+
+
+ +```{image} ../images/Board/sotirios.jpg +--- +alt: Sotirios Panagiotou +height: 150px +--- +``` + +**Sotirios Panagiotou**
+PhD candidate
+Erasmus Medical Center
+Rotterdam, Netherlands
+[Website](https://scholar.google.com/citations?user=8XdZ5jUAAAAJ&hl=en&oi=ao) + +
+ +
+
+
+ +```{image} ../images/Board/salva.png +--- +alt: Salvador Dura-Bernal +height: 150px +--- +``` + +**Salvador Dura-Bernal**
+SUNY Downstate
+Brooklyn, USA
+[Website](http://www.neurosimlab.com/users/salvador-dura-bernal) + +
+ +
+
+
+ +```{image} ../images/Board/padraig2.jpeg +--- +alt: Padraig Gleeson +height: 150px +--- +``` + +**Padraig Gleeson**
+University College London
+UK
+[Website](http://www.opensourcebrain.org/users/4) + +
+ +
+
+
+ +```{image} ../images/Board/boris.jpg +--- +alt: Boris Marin +height: 150px +--- +``` + +**Boris Marin**
+Universidade Federal do ABC
+Brazil
+[Website](https://www.opensourcebrain.org/users/67) + + +
+ +
+
+
+ +```{image} ../images/Board/ankur.png +--- +alt: Ankur Sinha +height: 150px +--- +``` + +**Ankur Sinha**
+University College London
+UK
+[Website](https://ankursinha.in) + +
+
+
+
+ +Information on past editors and elections can be found {ref}`here `. + +## Procedures + +The procedures for election of the editorial board, its responsibilities, size and activities were heavily inspired by other initiatives like [SBML](http://sbml.org/Documents/SBML_Development_Process#The_SBML_Editors), that have had successful editorial teams for many years. +The [COMBINE initiative](http://co.mbine.org/standards) seeks to promote community developed standards in computational biology, and the NeuroML editorial board will work with this initiative to ensure best practices in specification preparation. + +## Responsibilities of NeuroML Editors + +Their main responsibilities are: + +- Defining and documenting the procedure for specification production: scope, release frequency, update procedures, form of specification (web based or single pdf, etc.). + This should be based on some or all of the recommendations for community based standards development from the COMBINE initiative. + These procedures for specification production will have to be agreed with the {ref}`Scientific Committee `. +- Preparing the core specification for the NeuroML language. +- Testing reference implementations of NeuroML compliant applications. +- Preparing a specification for the LEMS language. + This can be a subset of the language supported by the reference implementations in Java (jLEMS) and Python (pyLEMS), but will have to cover all of the LEMS elements required to specify the ComponentType definitions for NeuroML 2. +- Responding to community queries about the specification. +- Establishing a procedure for incorporating major changes into the specification (in cooperation with the {ref}`Scientific Committee `). + +Participation in the editorial board will be on a volunteer basis, there is no central funding to support this work. diff --git a/_sources/NeuroMLOrg/BoardHistory.md b/_sources/NeuroMLOrg/BoardHistory.md new file mode 100644 index 00000000..89088aa9 --- /dev/null +++ b/_sources/NeuroMLOrg/BoardHistory.md @@ -0,0 +1,68 @@ +(neuromlorg:boardhistory)= +# History of the NeuroML Editorial Board + +This page documents the previous members of the NeuroML Board. + +## Initial election of editors (2013) + +The first election of an editorial board for NeuroML took place in May/June 2013. + +- The electorate consisted of the members of the NeuroML mailing lists on 3rd May 2013. +- Anyone on these lists could nominate someone to be an editor. Self nominations were also allowed. +- The three candidates who received the highest number of votes will serve three year terms and the two with the next highest number of votes will serve two year terms. +- Nicolas Le Novère (lenov -at- babraham.ac.uk) was the returning officer for this initial election. + + +## Election of editors (2015) + +The second election of an editorial board for NeuroML took place in June/July 2015. + +- The electorate consisted of the members of the NeuroML mailing lists on 18 June 2015. +- Anyone on these lists could nominate someone to be an editor. Self nominations were also allowed. +- The two candidates who received the highest number of votes would serve three year terms. +- Nicolas Le Novère (lenov -at- babraham.ac.uk) was the returning officer for this election. +- Results were announced [here](https://sourceforge.net/p/neuroml/mailman/message/34331970/). + +## Election of editors (2016) +The third election of an editorial board for NeuroML took place in July/August 2016. + +- The electorate consisted of the members of the NeuroML mailing lists on 18 July 2016. +- Anyone on these lists could nominate someone to be an editor. Self nominations were also allowed. +- The three candidates who received the highest number of votes would serve three year terms. +- Nicolas Le Novère (lenov -at- babraham.ac.uk) was the returning officer for this election. + +## Election of editors (2018) +The fourth election of an editorial board for NeuroML took place in Nov/Dec 2018. + +- The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years. +- Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed. +- The two candidates who received the highest number of votes would serve three year terms. +- Salvador Dura-Bernal was elected outright on the first round of voting and Andrew Davison was elected in a run off between the two next highest placed candidates who received the same number of votes. +- Malin Sandstrom at the INCF was the returning officer for this election. + +## Election of editors (2019) +The fifth election of an editorial board for NeuroML took place in Nov/Dec 2019. + +- The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years. +- Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed. +- The three candidates who received the highest number of votes would serve three year terms. +- Padraig Gleeson, Boris Marin and Justas Birgiolas were nominated, and eventually all elected to serve as editors. +- Malin Sandstrom at the INCF was the returning officer for this election. + +## Election of editors (2022) +The sixth election of an editorial board for NeuroML took place in Nov/Dec 2021. + +- The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years. +- Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed. +- The three candidates who received the highest number of votes would serve three year terms. +- Salvador Dura-Bernal and Ankur Sinha were nominated, and eventually all elected to serve as editors. +- Sharon Crook was the returning officer for this election. + +## Election of editors (2024) +The seventh election of an editorial board for NeuroML took place in Nov/Dec 2023. + +- The electorate consisted of the members of the NeuroML mailing lists as well as anyone who had made significant contributions to any of the NeuroML GitHub repositories in the past 3 years. +- Anyone on the electorate could nominate someone to be an editor. Self nominations were also allowed. +- The three candidates who received the highest number of votes would serve three year terms. +- Padraig Gleeson, Boris Marin, Sotirios Panagiotou and Subhasis Ray were nominated. Padraig Gleeson, Boris Marin, Sotirios Panagiotou received highest votes and were elected to serve as editors. +- Cengiz Gunay was the returning officer for this election. diff --git a/_sources/NeuroMLOrg/BoardMeetingReports.md b/_sources/NeuroMLOrg/BoardMeetingReports.md new file mode 100644 index 00000000..195b3a19 --- /dev/null +++ b/_sources/NeuroMLOrg/BoardMeetingReports.md @@ -0,0 +1,64 @@ +(neuromlevents:meetings)= +# Workshop and Meeting reports + +Information and minutes of various NeuroML meetings can be found here. +```{list-table} +:header-rows: 1 +:widths: 20, 20, 60 + +* - Meeting + - Location + - Summary +* - 2021 NeuroML Development workshop & Editorial Board Meeting + - Online at COMBINE 2021 + - A NeuroML development workshop was held as part of the annual COMBINE meeting in October 2021.
+ {ref}`More info `. +* - 2019 NeuroML Editorial Board Meeting + - CNS*2019 Meeting, Barcelona + - The fifth NeuroML Editorial Board Meeting took place at the CNS meeting in Barcelona, Monday 15th July, 2019.
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLEditorialBoardMeeting2019.pdf). +* - 2018 NeuroML Editorial Board Meeting + - Online + - The fourth NeuroML Editorial Board Meeting took place via video conference on 6th July 2018 between the NeuroML Editorial Board and interested members of the community to get an update on all current NeuroML related activities.
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLEditorialBoardMeeting2018.pdf). +* - 2016 NeuroML Editorial Board Meeting + - Janelia Research Campus, Virginia, USA + - The third NeuroML Editorial Board Meeting took place after the **Collaborative Development of Data-Driven Models of Neural Systems** conference held at Janelia Research Campus in Sept 2016. + More details on the main conference can be found [here](https://www.janelia.org/you-janelia/conferences/collaborative-development-data-driven-models-neural-systems).
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLEditorialBoardMeeting2016.pdf). +* - 2015 NeuroML Editorial Board Meeting @ OSB 2015 + - Alghero, Sardinia, Italy + - The second NeuroML Editorial Board Meeting took place prior to the Open Source Brain 2015 meeting held in Sardinia. + More details on the main meeting can be found [here](http://opensourcebrain.org/docs/Help/Meetings#OSB_2015).
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLEditorialBoardMeeting2015.pdf). +* - 2014 NeuroML Editorial Board Meeting @ OSB 2014 + - Alghero, Sardinia, Italy + - The first official NeuroML Editorial Board Meeting took place prior to the Open Source Brain 2014 meeting held in Sardinia. + More details on the main meeting can be found [here](http://opensourcebrain.org/docs/Help/Meetings#OSB_2014).
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLEditorialBoardMeeting2014.pdf). +* - 2013 NeuroML Meeting Development Workshop @ OSB 2013 + - Alghero, Sardinia, Italy + - The NeuroML Development Workshop was merged into the Open Source Brain kickoff meeting in Alghero, Sardinia. + More details on this meeting can be found [here](http://www.opensourcebrain.org/projects/osb/wiki/Meetings). Discussions on the state of NeuroML and future developments took place during the main meeting. +* - 2012 NeuroML Development Workshop + - Informatics Forum, Edinburgh, UK + - The NeuroML workshop at was combined with the [BrainScaleS](http://brainscales.kip.uni-heidelberg.de/) (previously FACETS) CodeJam meeting.
+ {ref}`Minutes `. +* - 2011 NeuroML Development Workshop + - University College London, UK + - A key outcome of third NeuroML Development Workshop was the creation of a Scientific Committee for NeuroML.
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLWorkshop2011.pdf). +* - 2010 NeuroML Development Workshop + - Arizona State University, USA + - The second NeuroML Development Workshop was held in Arizona State University to plan for version 2.0 of the NeuroML model description language. + There was also a Symposium on Multiscale Approaches to Understanding Neural Plasticity held at ASU before the main meeting and a number of tutorials on software for multiscale modeling given by the meeting participants on the following day.
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLWorkshop2010.pdf). +* - 2009 NeuroML Development Workshop + - University College London, UK + - The focus of the workshop was to refine the specifications for describing models of channel kinetics and the biophysical properties of cells. + Special thanks to the Wellcome Trust, the INCF, and the NSF for their generous support of this endeavour.
+ [Minutes](https://docs.neuroml.org/_static/files/NeuroMLWorkshop2009.pdf). +* - 2008 CNS Workshop + - Portland, Oregon, USA + - Padraig Gleeson and Sharon Crook moderated a workshop on "Interoperability of Software for Computational and Experimental Neuroscience" at the 2008 Computational Neuroscience Meeting. +``` diff --git a/_sources/NeuroMLOrg/CoC.md b/_sources/NeuroMLOrg/CoC.md new file mode 100644 index 00000000..05a2994f --- /dev/null +++ b/_sources/NeuroMLOrg/CoC.md @@ -0,0 +1,13 @@ +(coc)= +# Code of Conduct + +Everyone is welcome in the NeuroML community. +We request everyone interacting on the NeuroML channels in any capacity to treat each other respectfully. +Please: + +- act in good faith +- be friendly, welcoming, respectful, and patient +- be mindful and considerate +- be open, use prefer and promote Open Science practices. + +If you experience or become aware of behaviour that does not adhere to the Code of Conduct, please contact the moderators of the channel/event you are in. diff --git a/_sources/NeuroMLOrg/CommunicationChannels.md b/_sources/NeuroMLOrg/CommunicationChannels.md new file mode 100644 index 00000000..0d166a8d --- /dev/null +++ b/_sources/NeuroMLOrg/CommunicationChannels.md @@ -0,0 +1,33 @@ +(contact)= +# Getting in touch + +We're happy to talk with users, developers and modellers about using NeuroML in their work. + +(contact:ml)= +## Mailing list + +For announcements, general discussion, queries, and troubleshooting related to NeuroML please use the mailing list: [https://lists.sourceforge.net/lists/listinfo/neuroml-technology](https://lists.sourceforge.net/lists/listinfo/neuroml-technology). + +(contact:chat)= +## Chat channels + +A Gitter/Matrix chat channels for queries are also available. +One can access it either via Gitter or Matrix/Element. + +- [Gitter](https://gitter.im/NeuroML/community) +- [Matrix/Element](https://matrix.to/#/!EQLdKYsJxEfGHAybdP:gitter.im?via=gitter.im&via=matrix.org) + +Please note that activity in these rooms depends on time zones and the availability of community members. +So, if you do not get a response soon, please post to the mailing list listed above or file an issue on GitHub as noted below. + +(contact:issues)= +## Issues related to the libraries or specification + +- Please file general issues related to NeuroML at the [NeuroML/NeuroML2 repository on GitHub](https://github.com/NeuroML/NeuroML2/issues). +- Please file issues related to LEMS and jLEMS at the [LEMS/jLEMS repository on GitHub](https://github.com/LEMS/jLEMS/issues). +- Additionally, please file issues related to the different NeuroML core tools at their individual {ref}`GitHub repositories `. + +(contact:social)= +## Social media + +You can follow NeuroML related updates on Twitter at [@NeuroML](https://twitter.com/NeuroML). diff --git a/_sources/NeuroMLOrg/Contributors.md b/_sources/NeuroMLOrg/Contributors.md new file mode 100644 index 00000000..75e7c4ac --- /dev/null +++ b/_sources/NeuroMLOrg/Contributors.md @@ -0,0 +1,146 @@ +(neuromlorg:contributors)= +# NeuroML contributors + +This page lists contributors to the various NeuroML and related repositories, listed in no particular order. +It is generated periodically, most recently on 04/09/23. See also the current {ref}`NeuroML Editorial Board` and the {ref}`Scientific Committee `. +The list of repositories can be seen on {ref}`the repositories page `. + + + +- [@pgleeson](https://github.com/pgleeson) +- [@tarelli](https://github.com/tarelli) +- [@borismarin](https://github.com/borismarin) +- [@sanjayankur31](https://github.com/sanjayankur31) +- [@mattearnshaw](https://github.com/mattearnshaw) +- [@adrianq](https://github.com/adrianq) +- [@epiasini](https://github.com/epiasini) +- [@RokasSt](https://github.com/RokasSt) +- [@dilawar](https://github.com/dilawar) +- [@russelljjarvis](https://github.com/russelljjarvis) +- [@FinnK](https://github.com/FinnK) +- [@kapilkd13](https://github.com/kapilkd13) +- [@gidili](https://github.com/gidili) +- [@wvangeit](https://github.com/wvangeit) +- [@hugh-osborne](https://github.com/hugh-osborne) +- [@lungd](https://github.com/lungd) +- [@orena1](https://github.com/orena1) +- [@JustasB](https://github.com/JustasB) +- [@ChihweiLHBird](https://github.com/ChihweiLHBird) +- [@rgerkin](https://github.com/rgerkin) +- [@ccluri](https://github.com/ccluri) +- [@mwatts15](https://github.com/mwatts15) +- [@34383c](https://github.com/34383c) +- [@andrisecker](https://github.com/andrisecker) +- [@jrieke](https://github.com/jrieke) +- [@scrook](https://github.com/scrook) +- [@jonc125](https://github.com/jonc125) +- [@davidt0x](https://github.com/davidt0x) +- [@doorkn-b](https://github.com/doorkn-b) +- [@shayan823](https://github.com/shayan823) +- [@ramcdougal](https://github.com/ramcdougal) +- [@lisphacker](https://github.com/lisphacker) +- [@dokato](https://github.com/dokato) +- [@robertcannon](https://github.com/robertcannon) +- [@JLLeitschuh](https://github.com/JLLeitschuh) +- [@waffle-iron](https://github.com/waffle-iron) +- [@volker01](https://github.com/volker01) +- [@theiera](https://github.com/theiera) +- [@apdavison](https://github.com/apdavison) +- [@vitorchaud](https://github.com/vitorchaud) +- [@hglabska](https://github.com/hglabska) +- [@adityagilra](https://github.com/adityagilra) +- [@kkalou](https://github.com/kkalou) +- [@avrama](https://github.com/avrama) +- [@osb-admin](https://github.com/osb-admin) +- [@tcstewar](https://github.com/tcstewar) +- [@jplang](https://github.com/jplang) +- [@marutosi](https://github.com/marutosi) +- [@edavis10](https://github.com/edavis10) +- [@winterheart](https://github.com/winterheart) +- [@jbbarth](https://github.com/jbbarth) +- [@jgoerzen](https://github.com/jgoerzen) +- [@h-mayorquin](https://github.com/h-mayorquin) +- [@harveymannering](https://github.com/harveymannering) +- [@acardona](https://github.com/acardona) +- [@rizland](https://github.com/rizland) +- [@SteMasoli](https://github.com/SteMasoli) +- [@MFarinella](https://github.com/MFarinella) +- [@yates9](https://github.com/yates9) +- [@Neurophile](https://github.com/Neurophile) +- [@EmmanuelleChaigneau](https://github.com/EmmanuelleChaigneau) +- [@slarson](https://github.com/slarson) +- [@usama57](https://github.com/usama57) +- [@dasj-osb](https://github.com/dasj-osb) +- [@muratkrty](https://github.com/muratkrty) +- [@arnabiswas](https://github.com/arnabiswas) +- [@souravsingh](https://github.com/souravsingh) +- [@pshwetank](https://github.com/pshwetank) +- [@albada](https://github.com/albada) +- [@anujanegi](https://github.com/anujanegi) +- [@nikiita013](https://github.com/nikiita013) +- [@kedoxey](https://github.com/kedoxey) +- [@ChristophMetzner](https://github.com/ChristophMetzner) +- [@evakh](https://github.com/evakh) +- [@BiaDarkia](https://github.com/BiaDarkia) +- [@Mcdonoughd](https://github.com/Mcdonoughd) +- [@sdrsd](https://github.com/sdrsd) +- [@salvadord](https://github.com/salvadord) +- [@kperun](https://github.com/kperun) +- [@ddanny](https://github.com/ddanny) +- [@jrmartin](https://github.com/jrmartin) +- [@koppen](https://github.com/koppen) +- [@tofi86](https://github.com/tofi86) +- [@yuba](https://github.com/yuba) +- [@smith](https://github.com/smith) +- [@abronte](https://github.com/abronte) +- [@dpbus](https://github.com/dpbus) +- [@korun](https://github.com/korun) +- [@wronglink](https://github.com/wronglink) +- [@clairvy](https://github.com/clairvy) +- [@RobFerrer](https://github.com/RobFerrer) +- [@ryansch](https://github.com/ryansch) +- [@yujideveloper](https://github.com/yujideveloper) +- [@chantra](https://github.com/chantra) +- [@mattmueller](https://github.com/mattmueller) +- [@tfliss](https://github.com/tfliss) +- [@BKriener](https://github.com/BKriener) +- [@JessyD](https://github.com/JessyD) +- [@jimboH](https://github.com/jimboH) +- [@vrhaynes](https://github.com/vrhaynes) +- [@abhineet99](https://github.com/abhineet99) +- [@filippomc](https://github.com/filippomc) +- [@kmantel](https://github.com/kmantel) +- [@zsinnema](https://github.com/zsinnema) +- [@Muhaddatha](https://github.com/Muhaddatha) +- [@Aiga115](https://github.com/Aiga115) +- [@vidhya-metacell](https://github.com/vidhya-metacell) +- [@vidhya-longani](https://github.com/vidhya-longani) +- [@SimaoBolota-MetaCell](https://github.com/SimaoBolota-MetaCell) +- [@Salam-Dalloul](https://github.com/Salam-Dalloul) +- [@ronaldonunes](https://github.com/ronaldonunes) +- [@pfeffer90](https://github.com/pfeffer90) +- [@stephprince](https://github.com/stephprince) +- [@hrani](https://github.com/hrani) +- [@upibhalla](https://github.com/upibhalla) +- [@asiaszmek](https://github.com/asiaszmek) +- [@subhacom](https://github.com/subhacom) +- [@keszybz](https://github.com/keszybz) +- [@aviralg](https://github.com/aviralg) +- [@malav4994](https://github.com/malav4994) +- [@bhanu151](https://github.com/bhanu151) +- [@analkumar2](https://github.com/analkumar2) +- [@bitdeli-chef](https://github.com/bitdeli-chef) +- [@physicalist](https://github.com/physicalist) +- [@anhknguyen96](https://github.com/anhknguyen96) +- [@Daksh1603](https://github.com/Daksh1603) +- [@yarikoptic](https://github.com/yarikoptic) +- [@vellamike](https://github.com/vellamike) +- [@clbarnes](https://github.com/clbarnes) +- [@mattions](https://github.com/mattions) +- [@lebedov](https://github.com/lebedov) +- [@baladkb](https://github.com/baladkb) +- [@jefferis](https://github.com/jefferis) +- [@mstimberg](https://github.com/mstimberg) +- [@arosh](https://github.com/arosh) +- [@unidesigner](https://github.com/unidesigner) +- [@lucasklmn](https://github.com/lucasklmn) diff --git a/_sources/NeuroMLOrg/Funding.md b/_sources/NeuroMLOrg/Funding.md new file mode 100644 index 00000000..e079f45f --- /dev/null +++ b/_sources/NeuroMLOrg/Funding.md @@ -0,0 +1,123 @@ +(neuromlorg:funding)= +# Funding and Acknowledgements + +The NeuroML effort has been made possible by funding from research councils in the UK, EU, and the USA. + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +```{image} ../images/Funders/mrc.jpg +--- +alt: UK Medical Research Council +align: center +--- +``` + + +[UK Medical Research Council](http://www.mrc.ac.uk/) + +
+ +```{image} ../images/Funders/bbsrc.gif +--- +alt: UK Biotechnology and Biological Sciences Research Council +align: center +--- +``` + + +[UK Biotechnology and Biological Sciences Research Council](http://www.bbsrc.ac.uk/) + +
+ +```{image} ../images/Funders/nih.gif +--- +alt: National Institutes of Health +align: center +--- +``` + + +[National Institutes of Health](http://www.nimh.nih.gov/) + +
+ +```{image} ../images/Funders/EUS_200px.gif +--- +alt: EU Synapse Project +align: center +--- +``` + + +[EU Synapse Project](http://www.eusynapse.mpg.de/) + +
+ +```{image} ../images/Funders/nsf.gif +--- +alt: National Science Foundation +align: center +--- +``` + + +[National Science Foundation](http://nsf.gov/) + +
+ +```{image} ../images/Funders/incf.png +--- +alt: International Neuroinformatics Coordinating Facility +align: center +--- +``` + + +[International Neuroinformatics Coordinating Facility](http://incf.org/) + +
+ +```{image} ../images/Funders/wtlogo.png +--- +alt: Wellcome +align: center +width: 30% +--- +``` + + +[Wellcome](http://www.wellcome.ac.uk/) + +
+
diff --git a/_sources/NeuroMLOrg/History.md b/_sources/NeuroMLOrg/History.md new file mode 100644 index 00000000..f3547cde --- /dev/null +++ b/_sources/NeuroMLOrg/History.md @@ -0,0 +1,53 @@ +(history)= +# A brief history of NeuroML + +% TODO: update links to refer to pages in the new docs here. + +## The early days + +The concept of NeuroML was first introduced in an article by Goddard et al. (2001) {cite}`Goddard2001`, following meetings at the University of Edinburgh where initial templates and an overall structure for a model description language for computational modelling in neuroscience were discussed. +The proposal extended general purpose structures for neuroscience data proposed by Gardner et al. (2001) {cite}`Gardner2001`. + +At that time, the design principles for NeuroML were closely linked with a specific software architecture in which a base application loads a range of plug-ins to handle different aspects of a simulation experiment. +The simulation platform [Neosim](http://www.neurogems.org/neosim2/) provided an implementation of this approach (Howell et al. 2003 {cite}`Howell2003`), and early NeuroML development was closely aligned to this architecture. +Fred Howell and Robert Cannon developed a software library, the NeuroML Development Kit (NDK), to simplify the process of working with XML serializations of models. +This library implemented a particular dialect of XML but did not define particular structures at the model description level. +Instead, Neosim plug-in developers were free to develop their own structures and serialize them via the NDK, in the hope that some consensus would emerge around the most useful ones. + +In practice, few developers beyond the Edinburgh group developed or used such structures and the resulting XML was too application specific to gain wider adoption. +The Neosim project was completed in 2005. + +## NeuroML v1.x + +Based on discussions with Howell and Cannon about the need to develop a consensus for describing widely used model components, Sharon Crook worked with the neuroanatomy community on a language for describing neuronal morphologies in XML, **MorphML** (Qi and Crook 2004 {cite}`Qi2004`). +At the same time, Padraig Gleeson, working with Angus Silver, was developing {ref}`neuroConstruct `, for generating neuronal simulations for the NEURON and GENESIS simulators (Gleeson et al. 2007 {cite}`Gleeson2007`), which had its own internal simulator independent representation for morphologies, channel and networks. + +It was agreed that these efforts should be merged under the banner of NeuroML, and the {ref}`v1.x structure of NeuroML ` was created. +A modular approach containing **MorphML**, **ChannelML** and **NetworkML** was adopted to allow application developers to support only those parts of the language needed by their application (Crook et al. 2007 {cite}`Crook2007`, Gleeson et al. 2010 {cite}`Gleeson2010`). +XML schema files for this version of the standard have been available since 2006. +The motivation, structure and functionality of this version is described in detail in Gleeson et al. 2010, while the specification of the language is outlined in the [Supporting Information](http://www.ploscompbiol.org/article/info:doi/10.1371/journal.pcbi.1000815#s5) of that publication. + +For converting NeuroML v1 models/files to NeuroML2, users can use {ref}`neuroConstruct `. + +## NeuroML v2.x - introducing LEMS... + +NeuroML2 development was started in 2011. +The main motivation for NeuroML2 was the lack of extensibility of NeuroML v1.x; every new model type which was introduced into the language required an update to the Schema, updates to the text documentation and an implementation in each of the native formats of the target simulators. +NeuroML2 is built on the **LEMS (Low Entropy Model Specification) language**, which allows machine readable definitions of the cell, channel and synapse models which form the core of the language. +This increases transparency of model structure and dynamics and facilitates automatic mapping of the models to multiple simulation formats. +More details on the structure of LEMS and how it is used in NeuroML2 can be found in Cannon et al. 2014 {cite}`Cannon2014` and {ref}`here `. + +In parallel with development of NeuroML2 and LEMS, software libraries for reading, writing and running simulations using the languages are under active development in Java ({ref}`jNeuroML `) and Python ({ref}`libNeuroML ` and {ref}`pyLEMS ` (see Vella et al. 2014 {cite}`Vella2014`) and {ref}`pyNeuroML `). + +The NeuroML specifications are developed by the {ref}`NeuroML Editorial Board ` and overseen by its {ref}`Scientific Committee `. +NeuroML specifications and the associated libraries are developed on GitHub and an overview of current activities can be found [here](https://github.com/NeuroML/NeuroML2/projects/1). + + +```{admonition} Recent releases of NeuroML2 +For full details on the recent releases of NeuroML see: [here](https://github.com/NeuroML/NeuroML2/blob/master/HISTORY.md). +``` + + +## The future + +{ref}`NeuroMLlite ` is under active development, which will significantly enhance the range of network models which can be expressed (in a concise JSON based format) and run in NeuroML supporting simulators. This work will form the basis of NeuroML v3.0. diff --git a/_sources/NeuroMLOrg/OutreachTraining.md b/_sources/NeuroMLOrg/OutreachTraining.md new file mode 100644 index 00000000..4ebd5f30 --- /dev/null +++ b/_sources/NeuroMLOrg/OutreachTraining.md @@ -0,0 +1,32 @@ +(neuromlorg:outreachtraining)= +# Outreach and training + +The NeuroML community has a strong record of participating in training and outreach activities. +Information on tutorials and workshops can be seen in the Events pages. + + +(neuromlorg:outreachtraining:gsoc)= +## Google summer of Code + +The NeuroML community participates annually in the [Google Summer of Code](https://summerofcode.withgoogle.com) under the [INCF](https://incf.org) organisation. +Projects are centred around the standardisation of published models in NeuroML to make these standardised versions available on the [Open Source Brain](https://opensourcebrain.org) platform and improving the NeuroML tools wherever possible. + + +(neuromlorg:outreachtraining:gsoc:2022)= +### 2022 + + +- Anuja Negi: [Simulating multiscale models of the mouse visual cortex in NeuroML](https://github.com/OpenSourceBrain/AllenInstituteNeuroML/blob/master/GSoC22.md) +- Shayan Shafquat: [Open source, cross simulator, large scale cortical models in NeuroML](https://github.com/OpenSourceBrain/BahlEtAl2012_ReducedL5PyrCell/tree/master/GSoC-2022#readme) + +(neuromlorg:outreachtraining:gsoc:past)= +### Other past GSoC projects + +- 2020: Ronaldo Nunes: [Conversion of large scale cortical models into PyNN/NeuroML](https://summerofcode.withgoogle.com/archive/2020/projects/4613840035119104) +- 2018: Jessica Dafflon: [Implementation of Two Neural Mass Models on the Open Source Brain Platform](https://summerofcode.withgoogle.com/archive/2018/projects/6446944821968896) +- 2017: Andras Ecker: [Conversion of a large scale hippocampal network model to NeuroML](https://summerofcode.withgoogle.com/archive/2017/projects/4673827971792896) +- 2016: Rokas Stanislavos: [Building cortical network models in NeuroML2 using procedural and declarative programming approaches](https://summerofcode.withgoogle.com/archive/2016/projects/5650639363244032) +- 2015: Justas Birgiolas: [Convert several large-scale thalamocortical models to NeuroML & PyNN](https://www.google-melange.com/archive/gsoc/2015/orgs/incf/projects/birgiolasj.html) +- 2014: Ramón Martínez Mayorquin: [Open source, cross simulator, large scale cortical models](https://www.google-melange.com/archive/gsoc/2014/orgs/incf/projects/h_mayorquin.html) +- 2013: Vitor Chaud: [Open source, cross simulator, models of cortical circuits](https://www.google-melange.com/archive/gsoc/2013/orgs/incf/projects/vitorchaud.html) +- 2012: Mike Vella: [Simulator-independent Python API for multi-compartmental modeling](https://www.google-melange.com/archive/gsoc/2012/orgs/incf/projects/vellamike.html) diff --git a/_sources/NeuroMLOrg/Repositories.md b/_sources/NeuroMLOrg/Repositories.md new file mode 100644 index 00000000..1736f33a --- /dev/null +++ b/_sources/NeuroMLOrg/Repositories.md @@ -0,0 +1,184 @@ + +(neuromlorg:repositories)= +# NeuroML repositories + +This page lists repositories related to NeuroML, listed in no particular order. +It is generated periodically, most recently on 04/09/23. A complete list of contributors can be seen {ref}`here `. + +For the status of tests on standardized NeuroML models on Open Source Brain, please see this page: https://github.com/OpenSourceBrain/.github/blob/main/testsheet/README.md. + + +- [NeuroML/org.neuroml.model](https://github.com/NeuroML/org.neuroml.model) +- [NeuroML/org.neuroml.model.injectingplugin](https://github.com/NeuroML/org.neuroml.model.injectingplugin) +- [NeuroML/org.neuroml1.model](https://github.com/NeuroML/org.neuroml1.model) +- [NeuroML/org.neuroml.visualiser](https://github.com/NeuroML/org.neuroml.visualiser) +- [NeuroML/NeuroML2](https://github.com/NeuroML/NeuroML2) +- [NeuroML/jNeuroML](https://github.com/NeuroML/jNeuroML) +- [NeuroML/org.neuroml.export](https://github.com/NeuroML/org.neuroml.export) +- [NeuroML/org.neuroml.import](https://github.com/NeuroML/org.neuroml.import) +- [NeuroML/NeuroMLToPOV-Ray](https://github.com/NeuroML/NeuroMLToPOV-Ray) +- [NeuroML/NML2_LEMS_Examples](https://github.com/NeuroML/NML2_LEMS_Examples) +- [NeuroML/NeuroMLWebsite](https://github.com/NeuroML/NeuroMLWebsite) +- [NeuroML/pyNeuroML](https://github.com/NeuroML/pyNeuroML) +- [NeuroML/neuroml2model](https://github.com/NeuroML/neuroml2model) +- [NeuroML/Presentations](https://github.com/NeuroML/Presentations) +- [NeuroML/NeuroMLToolbox](https://github.com/NeuroML/NeuroMLToolbox) +- [NeuroML/NeuroML_API](https://github.com/NeuroML/NeuroML_API) +- [NeuroML/NetworkShorthand](https://github.com/NeuroML/NetworkShorthand) +- [NeuroML/mod2neuroml](https://github.com/NeuroML/mod2neuroml) +- [NeuroML/neuroml2modelLite](https://github.com/NeuroML/neuroml2modelLite) +- [NeuroML/NeuroMLlite](https://github.com/NeuroML/NeuroMLlite) +- [NeuroML/Documentation](https://github.com/NeuroML/Documentation) +- [NeuroML/.github](https://github.com/NeuroML/.github) +- [LEMS/pylems](https://github.com/LEMS/pylems) +- [LEMS/jLEMS](https://github.com/LEMS/jLEMS) +- [LEMS/LEMS](https://github.com/LEMS/LEMS) +- [LEMS/org.lemsml.model](https://github.com/LEMS/org.lemsml.model) +- [LEMS/expr-parser](https://github.com/LEMS/expr-parser) +- [LEMS/lems-domogen-maven-plugin](https://github.com/LEMS/lems-domogen-maven-plugin) +- [OpenSourceBrain/CA1PyramidalCell](https://github.com/OpenSourceBrain/CA1PyramidalCell) +- [OpenSourceBrain/OSB_API](https://github.com/OpenSourceBrain/OSB_API) +- [OpenSourceBrain/CerebellarNucleusNeuron](https://github.com/OpenSourceBrain/CerebellarNucleusNeuron) +- [OpenSourceBrain/GranCellLayer](https://github.com/OpenSourceBrain/GranCellLayer) +- [OpenSourceBrain/GranCellRothmanIf](https://github.com/OpenSourceBrain/GranCellRothmanIf) +- [OpenSourceBrain/GranCellSolinasEtAl10](https://github.com/OpenSourceBrain/GranCellSolinasEtAl10) +- [OpenSourceBrain/GranuleCell](https://github.com/OpenSourceBrain/GranuleCell) +- [OpenSourceBrain/GranuleCellVSCS](https://github.com/OpenSourceBrain/GranuleCellVSCS) +- [OpenSourceBrain/IzhikevichModel](https://github.com/OpenSourceBrain/IzhikevichModel) +- [OpenSourceBrain/MainenEtAl_PyramidalCell](https://github.com/OpenSourceBrain/MainenEtAl_PyramidalCell) +- [OpenSourceBrain/PurkinjeCell](https://github.com/OpenSourceBrain/PurkinjeCell) +- [OpenSourceBrain/RothmanEtAl_KoleEtAl_PyrCell](https://github.com/OpenSourceBrain/RothmanEtAl_KoleEtAl_PyrCell) +- [OpenSourceBrain/SolinasEtAl-GolgiCell](https://github.com/OpenSourceBrain/SolinasEtAl-GolgiCell) +- [OpenSourceBrain/VervaekeEtAl-GolgiCellNetwork](https://github.com/OpenSourceBrain/VervaekeEtAl-GolgiCellNetwork) +- [OpenSourceBrain/Thalamocortical](https://github.com/OpenSourceBrain/Thalamocortical) +- [OpenSourceBrain/PyloricNetwork](https://github.com/OpenSourceBrain/PyloricNetwork) +- [OpenSourceBrain/MorrisLecarModel](https://github.com/OpenSourceBrain/MorrisLecarModel) +- [OpenSourceBrain/StriatalSpinyProjectionNeuron](https://github.com/OpenSourceBrain/StriatalSpinyProjectionNeuron) +- [OpenSourceBrain/CelegansNeuromechanicalGaitModulation](https://github.com/OpenSourceBrain/CelegansNeuromechanicalGaitModulation) +- [OpenSourceBrain/PospischilEtAl2008](https://github.com/OpenSourceBrain/PospischilEtAl2008) +- [OpenSourceBrain/Drosophila_Projection_Neuron](https://github.com/OpenSourceBrain/Drosophila_Projection_Neuron) +- [OpenSourceBrain/NengoNeuroML](https://github.com/OpenSourceBrain/NengoNeuroML) +- [OpenSourceBrain/NeuroElectroSciUnit](https://github.com/OpenSourceBrain/NeuroElectroSciUnit) +- [OpenSourceBrain/NeuroMorpho](https://github.com/OpenSourceBrain/NeuroMorpho) +- [OpenSourceBrain/redmine](https://github.com/OpenSourceBrain/redmine) +- [OpenSourceBrain/CSAShowcase](https://github.com/OpenSourceBrain/CSAShowcase) +- [OpenSourceBrain/L5bPyrCellHayEtAl2011](https://github.com/OpenSourceBrain/L5bPyrCellHayEtAl2011) +- [OpenSourceBrain/neuroConstructShowcase](https://github.com/OpenSourceBrain/neuroConstructShowcase) +- [OpenSourceBrain/PinskyRinzelModel](https://github.com/OpenSourceBrain/PinskyRinzelModel) +- [OpenSourceBrain/Brunel2000](https://github.com/OpenSourceBrain/Brunel2000) +- [OpenSourceBrain/NineMLShowcase](https://github.com/OpenSourceBrain/NineMLShowcase) +- [OpenSourceBrain/BrianShowcase](https://github.com/OpenSourceBrain/BrianShowcase) +- [OpenSourceBrain/MUSICShowcase](https://github.com/OpenSourceBrain/MUSICShowcase) +- [OpenSourceBrain/SBMLShowcase](https://github.com/OpenSourceBrain/SBMLShowcase) +- [OpenSourceBrain/HindmarshRose1984](https://github.com/OpenSourceBrain/HindmarshRose1984) +- [OpenSourceBrain/FitzHugh-Nagumo](https://github.com/OpenSourceBrain/FitzHugh-Nagumo) +- [OpenSourceBrain/BluehiveShowcase](https://github.com/OpenSourceBrain/BluehiveShowcase) +- [OpenSourceBrain/NIFShowcase](https://github.com/OpenSourceBrain/NIFShowcase) +- [OpenSourceBrain/CATMAIDShowcase](https://github.com/OpenSourceBrain/CATMAIDShowcase) +- [OpenSourceBrain/VogelsSprekelerEtAl2011](https://github.com/OpenSourceBrain/VogelsSprekelerEtAl2011) +- [OpenSourceBrain/cereb_grc_mc](https://github.com/OpenSourceBrain/cereb_grc_mc) +- [OpenSourceBrain/NSGPortalShowcase](https://github.com/OpenSourceBrain/NSGPortalShowcase) +- [OpenSourceBrain/ACnet2](https://github.com/OpenSourceBrain/ACnet2) +- [OpenSourceBrain/CNOShowcase](https://github.com/OpenSourceBrain/CNOShowcase) +- [OpenSourceBrain/DentateGyrus2005](https://github.com/OpenSourceBrain/DentateGyrus2005) +- [OpenSourceBrain/ghk-nernst](https://github.com/OpenSourceBrain/ghk-nernst) +- [OpenSourceBrain/korngreen-pyramidal](https://github.com/OpenSourceBrain/korngreen-pyramidal) +- [OpenSourceBrain/neuroConstruct_to_be_deleted](https://github.com/OpenSourceBrain/neuroConstruct_to_be_deleted) +- [OpenSourceBrain/NEURONShowcase](https://github.com/OpenSourceBrain/NEURONShowcase) +- [OpenSourceBrain/LarkumEtAl2009](https://github.com/OpenSourceBrain/LarkumEtAl2009) +- [OpenSourceBrain/GPUShowcase](https://github.com/OpenSourceBrain/GPUShowcase) +- [OpenSourceBrain/FPGAShowcase](https://github.com/OpenSourceBrain/FPGAShowcase) +- [OpenSourceBrain/FarinellaEtAl_NMDAspikes](https://github.com/OpenSourceBrain/FarinellaEtAl_NMDAspikes) +- [OpenSourceBrain/BlueBrainProjectShowcase](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase) +- [OpenSourceBrain/OSB_Metadata](https://github.com/OpenSourceBrain/OSB_Metadata) +- [OpenSourceBrain/OSB_Status](https://github.com/OpenSourceBrain/OSB_Status) +- [OpenSourceBrain/osb-model-validation](https://github.com/OpenSourceBrain/osb-model-validation) +- [OpenSourceBrain/ModelDBShowcase](https://github.com/OpenSourceBrain/ModelDBShowcase) +- [OpenSourceBrain/OSB_Documentation](https://github.com/OpenSourceBrain/OSB_Documentation) +- [OpenSourceBrain/V1NetworkModels](https://github.com/OpenSourceBrain/V1NetworkModels) +- [OpenSourceBrain/PotjansDiesmann2014](https://github.com/OpenSourceBrain/PotjansDiesmann2014) +- [OpenSourceBrain/AllenInstituteNeuroML](https://github.com/OpenSourceBrain/AllenInstituteNeuroML) +- [OpenSourceBrain/StochasticityShowcase](https://github.com/OpenSourceBrain/StochasticityShowcase) +- [OpenSourceBrain/VierlingClaassenEtAl2010](https://github.com/OpenSourceBrain/VierlingClaassenEtAl2010) +- [OpenSourceBrain/OSB_Videos](https://github.com/OpenSourceBrain/OSB_Videos) +- [OpenSourceBrain/Contribute](https://github.com/OpenSourceBrain/Contribute) +- [OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes](https://github.com/OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes) +- [OpenSourceBrain/MiglioreEtAl14_OlfactoryBulb3D](https://github.com/OpenSourceBrain/MiglioreEtAl14_OlfactoryBulb3D) +- [OpenSourceBrain/WeilerEtAl08-LaminarCortex](https://github.com/OpenSourceBrain/WeilerEtAl08-LaminarCortex) +- [OpenSourceBrain/Cerebellum3DDemo](https://github.com/OpenSourceBrain/Cerebellum3DDemo) +- [OpenSourceBrain/dLGNinterneuronHalnesEtAl2011](https://github.com/OpenSourceBrain/dLGNinterneuronHalnesEtAl2011) +- [OpenSourceBrain/GranularLayerSolinasNieusDAngelo2010](https://github.com/OpenSourceBrain/GranularLayerSolinasNieusDAngelo2010) +- [OpenSourceBrain/CommunityModellingCA1](https://github.com/OpenSourceBrain/CommunityModellingCA1) +- [OpenSourceBrain/FergusonEtAl2014-CA1PyrCell](https://github.com/OpenSourceBrain/FergusonEtAl2014-CA1PyrCell) +- [OpenSourceBrain/VERTEXShowcase](https://github.com/OpenSourceBrain/VERTEXShowcase) +- [OpenSourceBrain/MOOSEShowcase](https://github.com/OpenSourceBrain/MOOSEShowcase) +- [OpenSourceBrain/recaptcha](https://github.com/OpenSourceBrain/recaptcha) +- [OpenSourceBrain/OpenCortex](https://github.com/OpenSourceBrain/OpenCortex) +- [OpenSourceBrain/OlfactoryTest](https://github.com/OpenSourceBrain/OlfactoryTest) +- [OpenSourceBrain/FergusonEtAl2013-PVFastFiringCell](https://github.com/OpenSourceBrain/FergusonEtAl2013-PVFastFiringCell) +- [OpenSourceBrain/M1NetworkModel](https://github.com/OpenSourceBrain/M1NetworkModel) +- [OpenSourceBrain/NESTShowcase](https://github.com/OpenSourceBrain/NESTShowcase) +- [OpenSourceBrain/Hippocampus3DDemo](https://github.com/OpenSourceBrain/Hippocampus3DDemo) +- [OpenSourceBrain/OSB_Samples](https://github.com/OpenSourceBrain/OSB_Samples) +- [OpenSourceBrain/org.geppetto.persistence](https://github.com/OpenSourceBrain/org.geppetto.persistence) +- [OpenSourceBrain/redmine_github_hook](https://github.com/OpenSourceBrain/redmine_github_hook) +- [OpenSourceBrain/PyNNShowcase](https://github.com/OpenSourceBrain/PyNNShowcase) +- [OpenSourceBrain/neuralensemble-docker](https://github.com/OpenSourceBrain/neuralensemble-docker) +- [OpenSourceBrain/WangBuzsaki1996](https://github.com/OpenSourceBrain/WangBuzsaki1996) +- [OpenSourceBrain/GolgiCellDendGapJunctions](https://github.com/OpenSourceBrain/GolgiCellDendGapJunctions) +- [OpenSourceBrain/NetPyNEShowcase](https://github.com/OpenSourceBrain/NetPyNEShowcase) +- [OpenSourceBrain/Poirazi2003-CA1PyramidalCell](https://github.com/OpenSourceBrain/Poirazi2003-CA1PyramidalCell) +- [OpenSourceBrain/Ferrante2009-DentateGyrusGranuleCell](https://github.com/OpenSourceBrain/Ferrante2009-DentateGyrusGranuleCell) +- [OpenSourceBrain/Hemond2008-CA3PyramidalCell](https://github.com/OpenSourceBrain/Hemond2008-CA3PyramidalCell) +- [OpenSourceBrain/geppetto-osb](https://github.com/OpenSourceBrain/geppetto-osb) +- [OpenSourceBrain/SynapticIntegration](https://github.com/OpenSourceBrain/SynapticIntegration) +- [OpenSourceBrain/NorenbergEtAl2010_DGBasketCell](https://github.com/OpenSourceBrain/NorenbergEtAl2010_DGBasketCell) +- [OpenSourceBrain/TheVirtualBrainShowcase](https://github.com/OpenSourceBrain/TheVirtualBrainShowcase) +- [OpenSourceBrain/tutorials](https://github.com/OpenSourceBrain/tutorials) +- [OpenSourceBrain/BartosEtAl2002](https://github.com/OpenSourceBrain/BartosEtAl2002) +- [OpenSourceBrain/destexhe_jcns_2009](https://github.com/OpenSourceBrain/destexhe_jcns_2009) +- [OpenSourceBrain/MouseLightShowcase](https://github.com/OpenSourceBrain/MouseLightShowcase) +- [OpenSourceBrain/BonoClopath2017](https://github.com/OpenSourceBrain/BonoClopath2017) +- [OpenSourceBrain/SpineShowcase](https://github.com/OpenSourceBrain/SpineShowcase) +- [OpenSourceBrain/SadehEtAl2017-InhibitionStabilizedNetworks](https://github.com/OpenSourceBrain/SadehEtAl2017-InhibitionStabilizedNetworks) +- [OpenSourceBrain/WilsonCowan](https://github.com/OpenSourceBrain/WilsonCowan) +- [OpenSourceBrain/MultiscaleISN](https://github.com/OpenSourceBrain/MultiscaleISN) +- [OpenSourceBrain/PINGnets](https://github.com/OpenSourceBrain/PINGnets) +- [OpenSourceBrain/DynaSimShowcase](https://github.com/OpenSourceBrain/DynaSimShowcase) +- [OpenSourceBrain/Amacrine](https://github.com/OpenSourceBrain/Amacrine) +- [OpenSourceBrain/del-Molino2017](https://github.com/OpenSourceBrain/del-Molino2017) +- [OpenSourceBrain/MejiasEtAl2016](https://github.com/OpenSourceBrain/MejiasEtAl2016) +- [OpenSourceBrain/NWBShowcase](https://github.com/OpenSourceBrain/NWBShowcase) +- [OpenSourceBrain/L23PyramidalCellTutorial](https://github.com/OpenSourceBrain/L23PyramidalCellTutorial) +- [OpenSourceBrain/ConnectivityShowcase](https://github.com/OpenSourceBrain/ConnectivityShowcase) +- [OpenSourceBrain/IonChannelGenealogyShowcase](https://github.com/OpenSourceBrain/IonChannelGenealogyShowcase) +- [OpenSourceBrain/TobinEtAl2017](https://github.com/OpenSourceBrain/TobinEtAl2017) +- [OpenSourceBrain/CalciumImagingDriftingGrating](https://github.com/OpenSourceBrain/CalciumImagingDriftingGrating) +- [OpenSourceBrain/PsyNeuLinkShowcase](https://github.com/OpenSourceBrain/PsyNeuLinkShowcase) +- [OpenSourceBrain/EbnerEtAl2019](https://github.com/OpenSourceBrain/EbnerEtAl2019) +- [OpenSourceBrain/OSBv2](https://github.com/OpenSourceBrain/OSBv2) +- [OpenSourceBrain/JoglekarEtAl18](https://github.com/OpenSourceBrain/JoglekarEtAl18) +- [OpenSourceBrain/BahlEtAl2012_ReducedL5PyrCell](https://github.com/OpenSourceBrain/BahlEtAl2012_ReducedL5PyrCell) +- [OpenSourceBrain/SussilloAndAbbott2009](https://github.com/OpenSourceBrain/SussilloAndAbbott2009) +- [OpenSourceBrain/DemirtasEtAl19](https://github.com/OpenSourceBrain/DemirtasEtAl19) +- [OpenSourceBrain/SinusoidalVoltageProtocols](https://github.com/OpenSourceBrain/SinusoidalVoltageProtocols) +- [OpenSourceBrain/ONNXShowcase](https://github.com/OpenSourceBrain/ONNXShowcase) +- [OpenSourceBrain/ServiceStatus](https://github.com/OpenSourceBrain/ServiceStatus) +- [OpenSourceBrain/ArborShowcase](https://github.com/OpenSourceBrain/ArborShowcase) +- [OpenSourceBrain/hh-testing](https://github.com/OpenSourceBrain/hh-testing) +- [OpenSourceBrain/HNN](https://github.com/OpenSourceBrain/HNN) +- [OpenSourceBrain/Documentation](https://github.com/OpenSourceBrain/Documentation) +- [OpenSourceBrain/GSoC_2021_OSB_NWB](https://github.com/OpenSourceBrain/GSoC_2021_OSB_NWB) +- [OpenSourceBrain/EDENShowcase](https://github.com/OpenSourceBrain/EDENShowcase) +- [OpenSourceBrain/BindsNETShowcase](https://github.com/OpenSourceBrain/BindsNETShowcase) +- [OpenSourceBrain/moose-core](https://github.com/OpenSourceBrain/moose-core) +- [OpenSourceBrain/.github](https://github.com/OpenSourceBrain/.github) +- [OpenSourceBrain/OSBv2_Showcase](https://github.com/OpenSourceBrain/OSBv2_Showcase) +- [OpenSourceBrain/DANDIArchiveShowcase](https://github.com/OpenSourceBrain/DANDIArchiveShowcase) +- [OpenSourceBrain/NeuroDataShare](https://github.com/OpenSourceBrain/NeuroDataShare) +- [OpenSourceBrain/OSB_homepage](https://github.com/OpenSourceBrain/OSB_homepage) +- [OpenSourceBrain/pynsgr](https://github.com/OpenSourceBrain/pynsgr) +- [NeuralEnsemble/libNeuroML](https://github.com/NeuralEnsemble/libNeuroML) +- [scrook/neuroml-db](https://github.com/scrook/neuroml-db) +- [NeuralEnsemble/neurotune](https://github.com/NeuralEnsemble/neurotune) +- [NeuralEnsemble/pyelectro](https://github.com/NeuralEnsemble/pyelectro) diff --git a/_sources/NeuroMLOrg/ScientificCommittee.md b/_sources/NeuroMLOrg/ScientificCommittee.md new file mode 100644 index 00000000..1d8c33b8 --- /dev/null +++ b/_sources/NeuroMLOrg/ScientificCommittee.md @@ -0,0 +1,206 @@ +(neuromlorg:ScientificCommittee)= +# NeuroML Scientific Committee + +The responsibilities of the NeuroML Scientific Committee are: +- To advise on the scientific focus of the NeuroML initiative; to ensure that the structure of the language is based on the latest knowledge of neuronal anatomy and physiology. +- To agree on the technical implementation for the core specifications (in collaboration with the {ref}`NeuroML Editorial Board`) and to ensure that best practices are encouraged in model specification. +- To promote NeuroML internationally, both the core specifications and the tools which support the language. +- To define the governance structure of the NeuroML Initiative and outline a path towards a specification process with dedicated, elected editors. +- To engage with other standardisation and databasing initiatives in the computational neuroscience and wider biology fields. +- To review and agree on extensions to the core specifications and the scope of the initiative; to address issues the community raises regarding the direction of the initiative. + +## Current Members + + +
+
+
+
+ +```{image} ../images/ScientificCommittee/bhalla.png +--- +alt: Upi Bhalla +height: 150px +--- +``` + +**Upi Bhalla**
+NCBS
+Bangalore, India
+[Website](http://www.ncbs.res.in/bhalla) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/avrama.jpg +--- +alt: Avrama Blackwell +height: 150px +--- +``` + +**Avrama Blackwell**
+Krasnow Institute of Advanced Studies
+George Mason University, USA
+[Website](http://krasnow1.gmu.edu/CENlab/avrama.html) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/hugo.png +--- +alt: Hugo Cornells +height: 150px +--- +``` + +**Hugo Cornells**
+K.U. Leuven
+Belgium
+[Website](http://neurospaces.sourceforge.net/) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/rsz_crook.jpg +--- +alt: Sharon Crook +height: 150px +--- +``` + +**Sharon Crook**
+Arizona State University
+USA
+[Website](https://iconlab.asu.edu/crook.html) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/andrew.jpg +--- +alt: Andrew Davison +height: 150px +--- +``` + +**Andrew Davison**
+CNRS, Gif-sur-Yvette
+France
+[Website](http://www.andrewdavison.info/) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/robertmcdougal.png +--- +alt: Robert McDougal +height: 150px +--- +``` + +**Robert McDougal**
+Yale University
+USA
+[Website](https://medicine.yale.edu/lab/shepherd/profile/robert_mcdougal/) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/lyle.png +--- +alt: Lyle Graham +height: 150px +--- +``` + +**Lyle Graham**
+Université Paris Descartes
+Paris, France
+[Website](http://lyle.neurophysics.eu/) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/cgunay.JPG +--- +alt: Cengiz Gunay +height: 150px +--- +``` + + +**Cengiz Gunay**
+Georgia Gwinnett College
+USA
+[Website](https://www.ggc.edu/about-ggc/directory/cengiz-gunay) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/michael.png +--- +alt: Michael Hines +height: 150px +--- +``` + +**Michael Hines**
+Yale University
+USA
+[Website](http://www.neuron.yale.edu/neuron/credits) + +
+ +
+
+
+ +```{image} ../images/ScientificCommittee/angus.png +--- +alt: Angus Silver +height: 150px +--- +``` + +**Angus Silver**
+University College London
+London, UK
+[Website](https://silverlab.org) + +
+ +
+
+
+ + +## Past Members + +(Note: past members who are currently members of the {ref}`NeuroML Editorial Board ` are not listed.) + +- Robert Cannon diff --git a/_sources/NeuroMLOrg/Standards.md b/_sources/NeuroMLOrg/Standards.md new file mode 100644 index 00000000..a03a4421 --- /dev/null +++ b/_sources/NeuroMLOrg/Standards.md @@ -0,0 +1,16 @@ +(initiative:overview_standards)= +# Overview of standards in neuroscience + + +(initiative:overview_standards:neuroml)= +## NeuroML as a standard + + +NeuroML is an [INCF endorsed standard](https://www.incf.org/sbp/neuroml). + +NeuroML is a [COMBINE official standard](http://co.mbine.org/standards/neuroml). + +```{admonition} Work in progress +:class: note +This page is a work in progress... +``` diff --git a/_sources/Reference/Glossary.md b/_sources/Reference/Glossary.md new file mode 100644 index 00000000..ae8a6b9c --- /dev/null +++ b/_sources/Reference/Glossary.md @@ -0,0 +1,3 @@ +# Glossary + +- XML: Extensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. (Read full entry on [Wikipedia](https://en.wikipedia.org/wiki/XML)) diff --git a/_sources/Reference/zBibliography.md b/_sources/Reference/zBibliography.md new file mode 100644 index 00000000..f558ea01 --- /dev/null +++ b/_sources/Reference/zBibliography.md @@ -0,0 +1,5 @@ +# Bibliography + +```{bibliography} ./references.bib +:all: +``` diff --git a/_sources/Userdocs/Conventions.md b/_sources/Userdocs/Conventions.md new file mode 100644 index 00000000..e1716194 --- /dev/null +++ b/_sources/Userdocs/Conventions.md @@ -0,0 +1,66 @@ +(userdocs:conventions)= +# Conventions + +This page documents various conventions in use in NeuroML. + +(userdocs:conventions:underscores)= +## Prefer underscores instead of spaces + +In general, please prefer underscores `_` instead of spaces wherever possible, in filenames and ids. + +(userdocs:conventions:nmlid)= +## Component IDs: NmlId + +Some Components take an `id` parameter of type `NmlId` to set an ID for them. +They can then be referred to using their IDs when constructing paths and so on. + +IDs of type `NmlId` in NeuroML are strings and have certain constraints: + +- they **must** start with an alphabet (either small or capital) or an underscore +- they may include alphabets, both small and capital letters, numbers and underscores + +IDs are also checked during validation, so if an ID does not follow these constraints, the validation will throw an error. + + +(userdocs:conventions:files)= +## File naming + +When naming different NeuroML files, we suggest the following suffixes: + +- `channel.nml` for NeuroML files describing ion channels, for example: `Na.channel.nml` +- `cell.nml` for NeuroML files describing cells, for example: `hh.cell.nml` +- `synapse.nml` for NeuroML files describing synapses, for example: `AMPA.synapse.nml` +- `net.nml` for NeuroML files describing networks of cells, for example: `excitatory.net.nml` + +For LEMS files that describe simulations of NeuroML models ({ref}`"LEMS Simulation files" `), we suggest that: + +- file names start with the `LEMS_` prefix, +- file names end in `xml` + +For example `LEMS_HH_Simulation.xml`. + +```{figure} ../images/lems_nml_files.png +:alt: LEMS Simulation file and NeuroML file +:align: center +:scale: 24 % + +Typical organisation for a NeuroML simulation. The main NeuroML model is specified in a file with the network (`*.net.nml`), which can include/point to files containing individual synapses (`*.synapse.nml`) or cell files (`*.cell.nml`). If the latter are conductance based, they may include external channel files (`*.channel.nml`). The main LEMS Simulation file only needs to include the network file, and tools for running simulations of the model refer to just this LEMS file. Exceptions to these conventions are frequent and simulations will run perfectly well with all the elements inside the main LEMS file, but using this scheme will maximise reusability of model elements. + +``` + +(userdocs:conventions:segments)= +## Neuron segments + +When naming segments in multi-compartmental neuron models, we suggest the following prefixes: + +- `axon_` for axonal segments +- `dend_` for dendritic segments +- `soma_` for somatic segments + +There are 3 specific recommended names for segment groups which contain **ALL** of the somatic, dendritic or axonal segments + +- `axon_group` for the group of all axonal segments +- `dendrite_group` for the group of all dendritic segments +- `soma_group` for the group of all somatic segments + +Ideally every segment should be a member of one and only one of these groups. diff --git a/_sources/Userdocs/ConvertingModels.md b/_sources/Userdocs/ConvertingModels.md new file mode 100644 index 00000000..bfbef02f --- /dev/null +++ b/_sources/Userdocs/ConvertingModels.md @@ -0,0 +1,173 @@ +(userdocs:creating_models:converting_conductance)= +# Converting models to NeuroML and sharing them on Open Source Brain + +```{admonition} Walk throughs available +:class: tip +Look at the {ref}`Walkthroughs chapter ` for worked examples. +``` +The figure below is taken from the supplementary information of the {ref}`Open Source Brain paper `, and gives a quick overview of the steps required and tools available for converting a model to NeuroML and sharing it on the OSB platform. + +```{figure} ../images/osb-conversion.png +:alt: Schamatic of process of converting models to NeuroML +:align: center +:width: 60 % + +Procedures and tools to convert models from native formats to NeuroML and PyNN (Taken from Gleeson et al. 2019 {cite}`Gleeson2019`) +``` + +## Step 1) Find the original model code + +While it should in principle be possible to create the model based only on the description in the accompanying publication, having the original code is invaluable. +The original code allows the identification of all parameters related to the model, and it is required to verify the dynamical behaviour of the NeuroML equivalent. + +Scripts for an increasing number of published models are available on [ModelDB](https://modeldb.science). +ModelDB models are also published as [GitHub repositories](https://github.com/ModelDBRepository). +Forks of these are also managed in the [Open Source Brain GitHub organization](https://github.com/opensourcebrain/) and indexed on [Open Source Brain version 2](https://v2.opensourcebrain.org/). + + +So, the first step is to obtain the original model code and verify that this can be run to reproduce the published results. + + +(userdocs:creating_models:converting_conductance:github)= +## Step 2) Create GitHub and OSB accounts for sharing the code + +### 2a) Sign up to GitHub and OSB + +Sign up to [GitHub](https://github.com/signup) to be able to share the updated code publicly. Next, sign up to [Open Source Brain](https://www.opensourcebrain.org/account/register), and adding a reference to your GitHub user account will help link between the two resources. + +### 2b) Create GitHub repository + +Create a new [GitHub repository](https://docs.github.com/en/repositories) for your new model. There are plenty of examples of repositories containing NeuroML [on OSB](https://github.com/orgs/OpenSourceBrain/repositories). It's fine to share the code under your own user account, but if you would like to host it at https://github.com/OpenSourceBrain, please [get in contact with the OSB team](https://docs.opensourcebrain.org/General/Contacts.html). + +Now you can commit the scripts for original version of the model to your GitHub repository. **Please check what the license/redistribution conditions are for the code!** Authors who have shared their code on [ModelDB](https://senselab.med.yale.edu/ModelDB/default) are generally happy for the code to be reused, but it is good to get in contact with them as a courtesy to let them know your plans with the model. They will generally be very supportive as long as the original publications are referenced, and will often have useful information on any updated versions of the model. Adding or updating a [README file](https://docs.opensourcebrain.org/OSBv1/Write_Your_Project_Documentation.html#add-a-readme-file-in-your-github-repository-and-reuse-it-on-your-osb-projects) will be valuable for anyone who comes across the model on GitHub. + +### 2c) Create OSB project + +Now you can create a project on OSB which will point to the GitHub repository and will be able to find any NeuroML models committed to it. You can also add a link back to the original archived version on ModelDB, and even reuse your README on GitHub as a description. For more details on this see [here](https://docs.opensourcebrain.org/OSBv1/Creating_Your_Own_Project.html). + + +## Step 3) Improve and test original model code + +With the original simulator code shared on GitHub, and a README updated to describe it, new users will be able to clone the repository and start using the code as shared by the authors. Some updates may be required and any changes from the original version will be recorded under the Git history visible on GitHub. + + +### 3a) Make simpler/modularised versions of original model scripts + +Many of the model scripts which get released on ModelDB aim to reproduce one or two of the figures from the associated publication. However, these scripts can be quite complex, and mix simulation with some analysis of the results. They don't always provide a single, simple run of the model with standard parameters, which would be the target for a first version of the model in NeuroML. + +Therefore it would be useful to create some additional scripts (reusing cell/channel definition files as much as possible) illustrating the baseline behaviour of the model, including: + +- A simple script with a single cell (or one for each if multiple cells present) - applying a simple current pulse into each (e.g. [example1](https://github.com/mbezaire/ca1/blob/development/NeuroML2/olm.hoc), [example2](https://github.com/OpenSourceBrain/MiglioreEtAl14_OlfactoryBulb3D/blob/master/NEURON/mitral.hoc)) +- A single compartment (soma only) example with all the ion channels (ideally one where channels can easily be added/commented out) - apply current pulse ([example](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NEURON/Test_Soma.hoc) in NEURON) +- A passive version of multi-compartmental cell with multiple locations recorded +- A multi-compartmental cell with multiple channels and calcium dynamics, with the channels specified in separate files + +These will be much easier to compare to equivalents in NeuroML. + +(userdocs:creating_models:converting_conductance:add_omv_tests)= +### 3b) Add OMV tests + +```{admonition} Optional, but recommended. +:class: dropdown tip +This step is optional, but highly recommended to create automated tests on the behaviour of the model. +``` +Once you have some scripts which illustrate (in plots/saved data) the baseline expected behaviour of your model (spiketimes, rate of firing etc.), it would be good to put some checks in place which can be run to ensure this behaviour stays consistent across changes/commits to your repository, different versions of the underlying simulator, as well as providing a target for what the NeuroML version of the model should produce. + +The **[Open Source Brain Model validation framework](https://github.com/OpenSourceBrain/osb-model-validation) (OMV)** is designed for exactly this, allowing small scripts to be added to your repository stating what files to execute in what simulation engine and what the expected properties of generated output should be. These tests can be run on your local machine during development, but can also be easily integrated with [GitHub Actions](https://github.com/features/actions), allowing tests across multiple simulators to be run every time there is a commit to the repository ([example](https://github.com/OpenSourceBrain/IzhikevichModel/actions/runs/1520638984)). + +To start using this for your project, install OMV and test running it on your local machine (`omv all`) on some standard examples (e.g. [Hay et al.](https://github.com/OpenSourceBrain/L5bPyrCellHayEtAl2011)). + +Add OMV tests for your native simulator scripts ([example](https://github.com/OpenSourceBrain/GranCellSolinasEtAl10/blob/master/NEURON/.test.nrnpy.omt)), e.g. test the spike times of cell when simple current pulse applied. Commit this file to GitHub, along with a GitHub Actions workflow ([example](https://github.com/OpenSourceBrain/IzhikevichModel/blob/master/.github/workflows/omv-ci.yml)), and look for runs under the Actions tab of your project on GitHub. + +Later, you can add OMV tests too for the equivalent NeuroML versions, reusing the Model Emergent Property (`*.mep`) file ([example](https://github.com/mbezaire/ca1/blob/development/NeuroML2/cells/tests/.test.sca.jnmlnrn.omt)), thus testing that the behaviours of the 2 versions are the same (within a certain tolerance). + +(userdocs:creating_models:converting_conductance:initialnml2)= +## 4) Create a version of the model in NeuroML 2 + +### 4a) Create a LEMS Simulation file to run the model + +A {ref}`LEMS Simulation file ` is required to specify how to run a simulation of the NeuroML model, how long to run, what to plot/save etc. Create a LEMS*.xml ([example](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/LEMS_Soma_AllNML2.xml)) with *.net.nml ([example](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/Soma_AllNML2.net.nml)) and *.cell.nml ([example](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/Soma_AllNML2.cell.nml)) for **a cell with only a soma** (don't try to match a full multi-compartmental cell with all channels to the original version at this early stage). + +Start off with only passive parameters (capacitance, axial resistance and 1 leak current) set; gradually add channels as in 4b) below; apply a current pulse and save soma membrane potential to file. + +Ensure all `*nml` files are {ref}`valid `. Ensure the `LEMS*.xml` runs with `jnml`; visually compare the behaviour with original simple script from the previous section. + +Ensure the `LEMS*.xml` runs with `jnml -neuron`, producing similar behaviour. If there is a good correspondence, add OMV tests for the NeuroML version, using the Model Emergent Property (`*.mep`) file from the original script's test. + +When ready, commit the LEMS/NeuroML code to GitHub. + + +(userdocs:creating_models:converting_conductance:convert_channels)= +### 4b) Convert channels to NeuroML + +Restructure/annotate/comment channel files in the original model to be as clear as possible and ideally have all use the same overall structure (e.g. see mod files [here](https://github.com/mbezaire/ca1/tree/development)). + +(Optional) Create a (Python) script/notebook which contains the core activation variable expressions for the channels; this can be useful to restructure/test/plot/alter units of the expressions before generating the equivalent in NeuroML ([example](https://github.com/OpenSourceBrain/PINGnets/blob/master/NeuroML2/ConvertChannels.ipynb)). + +If you are using NEURON, use `pynml-modchananalysis` to generate plots of the activation variables for the channels in the mod files ([example1](https://github.com/NeuroML/pyNeuroML/blob/master/examples/analyseNaMod.sh), [example2](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NEURON/analyse.sh)). + +Start from an existing similar example of an ion channel in NeuroML ([examples1](https://github.com/OpenSourceBrain/AllenInstituteNeuroML/tree/master/CellTypesDatabase/models/NeuroML2), [examples2](https://github.com/RokasSt/Thalamocortical/tree/master/NeuroML2/channels), [examples3](https://github.com/mbezaire/ca1/tree/development/NeuroML2/channels)). + +Use `pynml-channelanalysis` to generate similar plots for your NeuroML based channels as your mod channels; these can easily be plotted for adding to your GitHub repo as summary pages ([example1](https://github.com/mbezaire/ca1/blob/development/NeuroML2/channels/channel_summary/README.md), [example2](https://github.com/OpenSourceBrain/MiglioreEtAl14_OlfactoryBulb3D/blob/master/NeuroML2/Channels/channel_summary/README.md)). + +Create a script to load the output of mod analysis and nml analysis and compare the outputs ([example](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/compare_nml2_mods.py)). + + +(userdocs:creating_models:converting_conductance:compare_single_comp)= +### 4c) Compare single compartment cell with channels + +Ensure you have a passive soma example in NeuroML which reproduces the behaviour of an equivalent passibe version inthe original format (from steps 3a and 4a above). + +Gradually test the cell with passive conductance and *each channel individually*. Plot v along with rate variables for each channel & compare how they look during current pulse ([example in NEURON](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NEURON/Test_Soma.hoc) vs [example in NeuroML](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/Soma_AllNML2.cell.nml) and [LEMS](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/LEMS_Soma_AllNML2.xml)) + +Test these in `jnml` first, then in Neuron with `jnml -neuron`. + +When you are happy with each of the channels, try the soma with all of the channels in place, with the same channel density as present in the soma of the original cell. + + +(userdocs:creating_models:converting_conductance:compare_multi_comp)= +### 4d) Compare multi-compartmental cell incorporating channels + +If the model was created in NEURON, export the 3D morphology from the original NEURON scripts using pyNeuroML ([example](https://github.com/OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes/blob/master/NeuroML2/export_nml2.py)); this will be easier if there is a hoc script with just a single cell instance as in section 1). While there is the option to use `includeBiophysicalProperties=True` and this will attempt to export the conductance densities on different groups, it may be better to consolidate these and add them afterwards using correctly named groups and the most efficient representation of conductance density to group relationships ([example](https://github.com/OpenSourceBrain/MiglioreEtAl14_OlfactoryBulb3D/blob/master/Python/Export/export_mitral.py)). + +```{code-block} python +from pyneuroml.neuron import export_to_neuroml2 +.. +export_to_neuroml2("test.hoc", "test.morphonly.cell.nml", includeBiophysicalProperties=False) +``` + +Alternatively manually add the `` elements to the cell file (as [here](https://github.com/OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes/blob/master/NeuroML2/L23_NoHotSpot.cell.nml#L16711)). + +You can use the tools for {ref}`visualising NeuroML Models ` to compare how these versions look agains the originals. + +As with the single compartment example, it's best to **start off with the passive case**, i.e no active channels on the soma or dendrites, and compare that to the original code (for membrane potential at multiple locations!), and gradually add channels. + +Many projects on OSB were originally converted from the original format (NEURON, GENESIS, etc.) to NeuroML v1 using {ref}`neuroConstruct ` (see [here](http://www.opensourcebrain.org/search_custom_field?f[]=43&op[43]=~&v[43][]=neuroConstruct) for a list of these). neuroConstruct has good support for export to NeuroML v2, and this code could form the basis for your conversion. More on using neuroConstruct [here](http://www.opensourcebrain.org/docs#Using_neuroConstruct_Based_Projects) and details on conversion of models to NeuroML v1 [here](http://www.neuroconstruct.org/docs/importneuron.html#Converting+mod+file%2FGENESIS+script+channels+into+ChannelML). + +Note: you can also export other morphologies from [NeuroMorpho.org](https://neuromorpho.org) in NeuroML2 format ([example](https://github.com/NeuralEnsemble/NeuroinformaticsTutorial/blob/master/Exercises/Exercise1_NeuroMorpho_to_OSB.md)) to try out different reconstructions of the same cell type with your complement of channels. + +(userdocs:creating_models:converting_conductance:reoptimise)= +## 4e) (Re)optimising cell models + +You can use [Neurotune](https://github.com/NeuralEnsemble/neurotune/) inside pyNeuroML to re-optimise your cell models. An example is [here](https://github.com/NeuroML/pyNeuroML/blob/master/examples/tuneHHCell.py), and a full sequence of optimising a NeuroML model against data in NWB can be found {ref}`here `. + + +## 4f) Create an equivalent network model in NeuroML + +Creating an equivalent of a complex network model originally built in hoc for example in NeuroML is not trivial. The guide to network building with libNeuroML {ref}`here ` is a good place to start. + +See also {ref}`NeuroMLlite `. + +## 5) Access, view and run your model on OSB + +When you're happy that a version of the model is behaving correctly in NeuroML, you can try visualising it on OSB. + +See [here](https://docs.opensourcebrain.org/OSBv1/Five_Minute_Introduction.html) for more details about viewing and simulating projects on OSB. + +## 6) Share and collaborate + +There is more information on how you can disseminate and promote your model once it is on OSB in the main documentation for that platform: +https://docs.opensourcebrain.org. + +Consider sharing parts of the model on {ref}`other NeuroML supporting resources ` (e.g. cell and channel files on NeuroML-DB). + diff --git a/_sources/Userdocs/CreatingNeuroMLModels.md b/_sources/Userdocs/CreatingNeuroMLModels.md new file mode 100644 index 00000000..0ef0be8c --- /dev/null +++ b/_sources/Userdocs/CreatingNeuroMLModels.md @@ -0,0 +1,19 @@ +(userdocs:creating_models)= +# Creating NeuroML models + +There are 3 main ways of developing a new model of a neuronal system in NeuroML + +**1) Reuse elements from previous NeuroML models** + +There are an increasing number of resources where you can find and analyse previously developed NeuroML models to use as the basis for a new model. See {ref}`here ` for details. + +(userdocs:creating_models:from_scratch)= +**2) Writing models from scratch using Python NeuroML tools** + +The toolchain around NeuroML means that it is possible to create a model in NeuroML format from the start. Please see the {ref}`Getting Started with NeuroML section ` for quick examples on how you can use {ref}`pyNeuroML ` to create NeuroML models and run them. + +**3) Convert a published model developed in a simulator specific format to NeuroML** + +Most computational models used in publications are released in the particular format used by the authors during their research, often in a general purpose simulator like {ref}`NEURON `. Many of these can be found on [ModelDB](https://senselab.med.yale.edu/ModelDB/default). Converting one of these to NeuroML format will mean that all further developments/modifications of the model will be standards compliant, and will give access to all of the NeuroML compliant tools for visualising/analysing/optimising/sharing the model, as well as providing multiple options for executing the model across multiple simulators. + +The next page is a **step by step guide** to creating a new NeuroML model based on an existing published model, verifying its behaviour, and sharing it with the community on the Open Source Brain platform. diff --git a/_sources/Userdocs/ExtendingNeuroMLv2.md b/_sources/Userdocs/ExtendingNeuroMLv2.md new file mode 100644 index 00000000..ed049e0a --- /dev/null +++ b/_sources/Userdocs/ExtendingNeuroMLv2.md @@ -0,0 +1,272 @@ +(userdocs:extending)= +# Extending NeuroML + +As a language, LEMS defines a set of built-in `types` which can be used together to build more user-defined types. +For example, Python defines `int`, `float`, `str` and so on as built-in types, and these can then be combined to define user defined types, classes. +An object of a particular class/type can be instantiated by supplying values for the members defined in the class/type. + +**ComponentTypes** in LEMS are similar to classes in Python. +They define the membership structure of the type, but they do not specify values for their members. +Once a ComponentType has been defined, an instance of it can be created by setting values for its members. +This object is referred to as a **Component** in LEMS. + +Having definitions in LEMS allows their re-use, and all new ComponentTypes can be submitted for inclusion to the NeuroMLv2 specification to be made accessible to other users. + +- Like NeuroML, LEMS also has a [well defined schema](https://github.com/LEMS/LEMS/tree/master/Schemas/LEMS) (XSD) that is used to validate LEMS XML files. +- Also similar to NeuroML, you can use the {ref}`LEMS Python tools ` to work with LEMS and do not need to work directly with the XML files. + +The NeuroML2 standard is a list of {ref}`curated LEMS ComponentTypes `. +In cases where the set of ComponentTypes defined in the NeuroML standard is not sufficient for a particular modelling project, new ComponentTypes can be defined to extend the NeuroMLv2 standard. + +(userdocs:extending:withneuroml)= +## Creating new ComponentTypes with existing NeuroML ComponentTypes + +Existing ComponentTypes defined in the NeuroMLv2 standard, when sufficient, should be used to create new ComponentTypes. +These new ComponentTypes, since they consist of NeuroMLv2 ComponentTypes, *will be valid against the NeuroMLv2 schema* (must use a {code}`` root element). +For convenience, the NeuroMLv2 schema includes a subset of the {ref}`LEMS elements `. + +An example of this type of extension of NeuroML can be see [here](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/NMC/NeuroML2/Ca_LVAst.channel.nml#L42) where a new Calcium dependent ion channel Component requires a new ComponentType {code}`Ca_LVAst_m_tau_tau` that implements the time course of the gate. + +However, please note that while the ComponentType will be valid NeuroML, the new Components (instances) one creates of this ComponentType (and models where Components are referenced/used) *will not*---since the NeuroML schema *does not know of the new ComponentType*. +The new Components (and the models) will be valid LEMS. +For this reason, while the ComponentType file will use a {code}`` root tag, the file containing its instantiated Components will use the {code}`` root tag. + +(userdocs:extending:withlems)= +## Creating new ComponentTypes with LEMS elements + +When ComponentTypes from the NeuroMLv2 standard are not sufficient for the creation of new ComponentTypes, one must use LEMS elements to do so. +The definitions of the {ref}`NeuroMLv2 standard core ComponentTypes ` are examples of this. + +(userdocs:extending:withlems:types)= +### LEMS elements + +The list of built-in types provided by LEMS can be seen {ref}`in the LEMS documentation `. +As the documentation notes, a ComponentType is the "Root element for defining component types". +It must contain a `name`, and can `extend` another ComponentType, thus inheriting its members/attributes. +Each ComponentType can contain members of other LEMS types: `Parameter`, `DerivedParameter`, `Dynamics`, `Exposure` and so on. + +(userdocs:extending:withlems:examplexml)= +### Example: Lorenz model for cellular convection + +To see how to create new ComponentTypes using LEMS, let us create one that is not neuroscience specific. +We will first create it using the plain XML and then see how it can be done using the Python pyLEMS API. + +For this example, we will use the Lorenz model for cellular convection {cite}`Lorenz1963`. +The [Wikipedia article](https://en.wikipedia.org/wiki/Lorenz_system#Overview) provides a short summary of the model, and the equations that govern it: + +\begin{align} +\frac{dx}{dt} &= \sigma (y - x) \\ +\frac{dy}{dt} &= x (\rho - z) - y \\ +\frac{dz}{dt} &= xy - \beta z +\end{align} + +So we can see here that we have three parameters: + +- $\sigma$ +- $\rho$ +- $\beta$ + +Next, `x`, `y`, and `z` are the *state variables* for this model, with initial values `x0`, `y0`, and `z0` respectively. +We also want to be able to observe the values of `x`, `y`, and `z`, so they must be *exposed* in the LEMS definition. + +Let us start with the XML definition of a ComponentType that will describe this model. +Each XML file must start with a `` "root node". +This includes information about the version of the LEMS schema that this document is valid against. +In this case, we document that this LEMS file should be valid against version 0.7.6 of the LEMS schema. + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + +``` + +Note that each parameter has a *dimension*, not a *unit*. +This is because LEMS allows us to use any valid units for each dimension, and takes care of the conversion factors and so on. +NeuroML also takes advantage of this LEMS feature, as noted {ref}`here `. + +Now, we can define the *dynamics* of the model, summarised in the equations above: + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + +``` + +Our LEMS file is almost complete. +However, notice that we have used `sec` in the dynamics to denote time but have not yet declared it. +We define `sec` as a *constant* whose value is defined in the ComponentType itself (and will not be set by us when instantiating a Component of this ComponentType): + +```{code-block} xml + +``` + +Also note that while we have defined this constant, we have not yet defined the `time` dimension or its units. +We can do that outside the ComponentType: + +```{code-block} xml + + + +``` + +We have defined two units for the time dimension, with their conversion factors. +LEMS will use this information to correctly convert all dimensions as required. +The NeuroMLv2 standard defines various dimensions and their units {ref}`in the schema ` for us to use. + +The complete LEMS file will be this: + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +We now have a complete LEMS model declaration. +To use this model, we need to create an instance of the ComponentType, a Component. +This requires us to set the values of various parameters of the defined model: + +```{code-block} xml + +``` + +Here, we've set parameters that result in the chaotic attractor regime. +We could also use different values for the parameters---like a class can have many many objects with different parameters, a ComponentType can have also have different Components. + +Note that one can also define a Component using the standard constructor form: +```{code-block} xml + +``` +The two forms are equivalent. +As with other conventions, either form can be used as long as it is used consistently. + +The `Include` element type allows us to modularise our models. +In NeuroML based models, we use it to break our model down into small independent reusable files. + +(userdocs:extending:lorenz:python)= +### Writing the model in Python using PyLEMS + +While the underlying format for NeuroML and LEMS is XML, Python is the suggested programming language for end users. +In this section we will see how the Lorenz model can be written using the {ref}`PyLEMS ` Python LEMS API. +The complete script is below: + +```{literalinclude} ./NML2_examples/LorenzLems.py +---- +language: python +---- +``` + +As you will see, the PyLEMS API exactly follows the XML constructs that we used before. +Running this script, let's call it `LorenzLems.py` gives us: + +```{code-block} console +$ python LorenzLems.py +Validating LEMS_lorenz.xml against https://raw.githubusercontent.com/LEMS/LEMS/development/Schemas/LEMS/LEMS_v0.7.6.xsd +It's valid! +``` + +The generated XML file is below. +As you can see, it is identical to the XML file that we wrote by hand in the previous section. +You will also see that the Python API also provides convenience functions, such as the `export_to_file` and `validate_lems` functions to quickly save your model to an XML file, and validate it. + +```{literalinclude} ./NML2_examples/LEMS_lorenz.xml +---- +language: xml +---- +``` + +We strongly suggest that users use the Python tools when working with both NeuroML and LEMS. +Not only is Python easier to read and write than XML, it also provides powerful programming constructs and has a rich ecosystem of scientific software. + +(userdocs:extending:examples)= +## Examples + +Here are some examples of Components written using LEMS to extend NeuroML that can be used as references. + +- [The Lorenz example XML source code](https://github.com/NeuroML/NeuroMLlite/blob/master/examples/test_files/Lorenz1963.xml) +- [An example script for building a LEMS model using Python](https://github.com/LEMS/pylems/blob/master/examples/apitest2.py) +- [Defining a new synapse in LEMS](https://github.com/OpenSourceBrain/BonoClopath2017/blob/master/NeuroML2/AMPA_NMDA.synapse.nml) +- [Defining an ion channel in LEMS](https://github.com/OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes/blob/master/NeuroML2/na.channel.nml) +- [Defining a new Calcium pool in LEMS](https://github.com/OpenSourceBrain/PospischilEtAl2008/blob/master/NeuroML2/channels/Ca/Ca.nml) diff --git a/_sources/Userdocs/FAQ.md b/_sources/Userdocs/FAQ.md new file mode 100644 index 00000000..cf85d1b6 --- /dev/null +++ b/_sources/Userdocs/FAQ.md @@ -0,0 +1,22 @@ +(userdocs:faq)= +# Frequently asked questions (FAQ) + +```{admonition} Please help improve the FAQ. +:class: note +This page lists some commonly asked questions related to NeuroML. +Please feel free to [open issues](https://github.com/NeuroML/Documentation/issues) to add more entries to this FAQ. +``` + +(userdocs:faq:zero_length_segments)= +## Are length 0 segments allowed in NeuroML? + +Discussion link: https://github.com/NeuroML/NeuroML2/issues/115 + +There are a lot of SWC reconstructions which have adjacent points, which would get converted to zero length segments. +This shouldn't be an issue for most visualisation applications, so no need for them to say that they can't visualise the cell if they see it's invalid. + +The `jnml -validate` option could throw a warning when it sees these segments, but currently doesn't (it could be added [here](https://github.com/NeuroML/org.neuroml.model/blob/development/src/main/java/org/neuroml/model/util/NeuroML2Validator.java#L199)). + +For individual simulators, they could have an issue with this, if they map each segment to a compartment (as Moose might), but for Neuron using cables/sections with multiple segments, it shouldn't matter as long as the section doesn't just have one segment. + +So ideally it should be the application which loads the NeuroML in (or the conversion/export code) which decides whether this is an issue. diff --git a/_sources/Userdocs/FindingNeuroMLModels.md b/_sources/Userdocs/FindingNeuroMLModels.md new file mode 100644 index 00000000..7ef8be69 --- /dev/null +++ b/_sources/Userdocs/FindingNeuroMLModels.md @@ -0,0 +1,84 @@ +(userdocs:finding_models)= +# Finding and sharing NeuroML models + + +There are an increasing number of repositories where you can find NeuroML models, many of which will are accepting submissions from the community who wish to share their work in this format. + +(userdocs:finding_models:neuromldb)= +## NeuroML-DB: The NeuroML Database + +```{admonition} Read the NeuroML-DB preprint! +:class: tip +A preprint of a manuscript describing NeuroML-DB and its current features is available [here](https://www.biorxiv.org/content/10.1101/2021.09.11.459920v1). +``` + +```{figure} ../images/NML-DB.png +:alt: NeuroML Database +:align: center + +The NeuroML Database contains NeuroML files for many [cells](https://neuroml-db.org/model_info?model_id=NMLCL000938) (left above), [channels](https://neuroml-db.org/model_info?model_id=NMLCH000103) (right) and synapses taken from Open Source Brain, Blue Brain Project, Allen Institute and more. + +``` + +The [NeuroML Database](https://neuroml-db.org/) is a relational database that provides a means for sharing NeuroML model descriptions and their components. +One of its goals is to contribute to an efficient tool chain for model development using NeuroML. +This emphasis allows the database design and subsequent searching to take advantage of this specific format. +In particular, the NeuroML database allows for efficient searches over the components of models and metadata that are associated with a hierarchical NeuroML model description. + +The NeuroML Database is developed and maintained by the [ICON Lab](https://iconlab.asu.edu/) at [Arizona State University](https://asu.edu/). + +To submit your NeuroML model to NeuroML-DB, please see the information on [this page](https://neuroml-db.org/about). + + +(userdocs:finding_models:osbv1)= +## Open Source Brain + +```{figure} ../images/OSBv1.png +:alt: Open Source Brain +:align: center + +Examples of NeuroML 2 models visualised on Open Source Brain. A) [Hodgkin Huxley model](https://www.opensourcebrain.org/projects/hodgkin-huxley-tutorial?explorer=https%3A%2F%2Fraw.githubusercontent.com%2Fopensourcebrain%2Ftutorials%2Fdevelopment%2Fmodels%2FhodgkinHuxley%2FGEPPETTO.json) interactive tutorial. B) Integrate and fire network model of cortical column ([Potjans and Diesmann 2014](https://www.opensourcebrain.org/projects/potjansdiesmann2014)), showing network connectivity. C) Cortical model with multicompartmental cells ([Traub et al. 2005](https://www.opensourcebrain.org/projects/thalamocortical)), showing network properties and simulated membrane potential activity. D) Model of C. elegans nervous system from [OpenWorm project](https://www.opensourcebrain.org/projects/c302/). All visualisation/analysis/simulation enabled due to models being in standardised NeuroML format. + +``` + +[Open Source Brain](https://www.opensourcebrain.org) is a platform for sharing, viewing, analysing, and simulating standardized models from different brain regions and species. +An index of various NeuroML models on Open Source Brain and their validation status can be seen [here](https://github.com/OpenSourceBrain/.github/blob/main/testsheet/README.md). + +To add your NeuroML model to Open Source Brain, please see the information on {ref}`this page `. + +(userdocs:finding_models:others)= +## Other related projects +```{note} +Needs introductory text. +``` + +(userdocs:finding_models:NeuroMorpho)= +## NeuroMorpho.Org + + +[NeuroMorpho.Org](https://neuromorpho.org) is a database of digitally reconstructed neurons. This resource can be used to retrieve reconstructed neuronal morphologies of multiple cell types from a number of species. The database can be browsed by neuron type, brain area, species, contributing lab, or cells can be searched for according to various morphometric criteria or the associated metadata. + +There is a utility present on the site to view the cells in 3D (based on Robert Cannon's Cvapp), which can also save the morphologies in NeuroML 2 format. + +A tutorial on getting data from NeuroMorpho.Org in NeuroML format can be found [here](https://github.com/NeuralEnsemble/NeuroinformaticsTutorial/blob/master/Exercises/Exercise1_NeuroMorpho_to_OSB.md). + + +(userdocs:finding_models:OpenWorm)= +## OpenWorm + +The [OpenWorm project](http://www.openworm.org) aims to create a simulation platform to build digital in-silico living systems, starting with a C. elegans virtual organism simulation. The simulations and associated tools are being developed in a fully open source manner. + +NeuroML is being used for the description of the 302 neurons in the [worm's nervous system](https://www.opensourcebrain.org/projects/c302/), both for morphological description of the cells and their electrical properties. + + + +(userdocs:finding_models:AllenInstitute)= +## Allen Institute + +Multiple cell models as produced by the [Allen Institute](https://alleninstitute.org/) as part of their large scale brain modelling efforts are available in NeuroML format [here](https://github.com/OpenSourceBrain/AllenInstituteNeuroML). + + +(userdocs:finding_models:BlueBrainProject)= +## Blue Brain Project + +The detailed cortical cell models from the [Blue Brain Project](http://bluebrain.epfl.ch) have been converted to NeuroML format, along with the ion channels from the [Channelpedia database](https://channelpedia.epfl.ch). See [here](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase) for details. diff --git a/_sources/Userdocs/GettingStarted.md b/_sources/Userdocs/GettingStarted.md new file mode 100644 index 00000000..57721363 --- /dev/null +++ b/_sources/Userdocs/GettingStarted.md @@ -0,0 +1,29 @@ +(userdocs:getting_started_neuroml)= +# Getting started with NeuroML + +The best way to understand NeuroML is to work through NeuroML examples to see how they are constructed and what they can do. +We present below a set of step-by-step guides to illustrate how models are written and simulated using NeuroML. + + + + + + + + +
        
+ + +| Link to guide | Description | Model life cycle stages | +| :------ | ----------- | ----------------------- | +| [Guide 1](https://docs.neuroml.org/Userdocs/NML2_examples/SingleNeuron.html) | Create and simulate a simple regular spiking Izhikevich neuron in NeuroML | Create, Validate, Simulate | +| [Guide 2](https://docs.neuroml.org/Userdocs/IzhikevichNetworkExample.html) | Create a network of two synaptically connected populations of Izhikevich neurons | Create, Validate, Visualise, Simulate | +| [Guide 3](https://docs.neuroml.org/Userdocs/SingleCompartmentHHExample.html) | Build and simulate a single compartment Hodgkin-Huxley neuron | Create, Validate, Visualise, Simulate | +| [Guide 4](https://docs.neuroml.org/Userdocs/MultiCompartmentOLMexample.html) | Create and simulate a multi compartment hippocampal OLM neuron | Create, Validate, Visualise, Simulate | +| [Guide 5](https://docs.neuroml.org/Userdocs/OptimisingNeuroMLModels) | Optimise/fit NeuroML models to experimental data | Create, Validate, Simulate, Fit | +| [Guide 6](https://docs.neuroml.org/Userdocs/CreatingNeuroMLModels.html\#converting-cell-models-to-neuroml-and-sharing-them-on-open-source-brain) | Guide to converting cell models to NeuroML and sharing them on Open Source Brain | Create, Validate, Simulate, Share | +| [Guide 7](https://docs.neuroml.org/Userdocs/NML2_examples/NeuroML-DB.html) | Create novel NeuroML models from components on NeuroML-DB | Reuse, Create, Validate, Simulate | +| [Guide 8](https://docs.neuroml.org/Userdocs/ExtendingNeuroMLv2.html\#example-lorenz-model-for-cellular-convection) | Extend NeuroML by creating a novel model type in LEMS | Create, Simulate | + + +You do not need to install any software on your computers to run many of the examples above. These examples are followed by a [Jupyter notebook](https://jupyter.org/index.html) for you to experiment with inside your browser ({ref}`more info `). diff --git a/_sources/Userdocs/HDF5.md b/_sources/Userdocs/HDF5.md new file mode 100644 index 00000000..894585b5 --- /dev/null +++ b/_sources/Userdocs/HDF5.md @@ -0,0 +1,24 @@ +(userdocs:hdf5)= +# HDF5 support + +The XML serializations of large NeuroML models can be prohibitive to store. +For such cases, NeuroML also includes support for saving models in the binary [HDF5](https://www.hdfgroup.org/solutions/hdf5) format via the [NeuroMLHdf5Writer in libNeuroML](https://libneuroml.readthedocs.io/en/stable/userdocs/writers.html#neuroml.writers.NeuroMLHdf5Writer). The same format can be exported also from the Java API ([example](https://github.com/NeuroML/org.neuroml.model/blob/master/src/test/java/org/neuroml/model/test/HDF5Test.java)). + +The format of the export is documented below: + + +- {ref}`Network ` is exported as a `network` HDF5 group with `id`, `notes`, and the `temperature` (optional) stored as attributes. +- {ref}`Population ` is exported as a group with id `population_` with `id`, `component`, `size`, `type`, and `property` tags stored as attributes. + - If the population is a {ref}`population list ` that includes {ref}`instances ` of cells, the locations of cells (x, y, z), these are stored in a 3 column table ("chunked array") with a row per instance. + +- {ref}`Projection ` is exported as a group with id `project_` with `id`, `type`, `presynapticPopulation`, `postSynapticPopulation`, `synapse` as attributes. + - {ref}`Connection ` and {ref}`ConnectionWD ` elements in projections are stored as rows in a table with the first two columns as the `pre_cell_id` and `post_cell_id` respectively, and the successive columns for the necessary attributes. + +- {ref}`ElectricalProjection ` is exported similar to Projection with the {ref}`ElectricalConnection `, {ref}`ElectricalConnectionInstance `, and {ref}`ElectricalConnectionInstanceW ` entries stored in tables. +- {ref}`ContinuousProjection ` is exported similar to Projection with the {ref}`ContinuousConnection `, {ref}`ContinuousConnectionInstance `, and {ref}`ContinuousConnectionInstanceW ` entries stored in tables. +- {ref}`InputList ` is exported similar to Projection with the {ref}`Input `, and {ref}`InputW ` entries stored in tables. + + +For more details, the source code of these export functions can be seen [here in the libNeuroML repository](https://github.com/NeuralEnsemble/libNeuroML/blob/2d8112178d8d82b07a20f8395ec22a23a6323a6c/neuroml/nml/helper_methods.py#L2548) and [here in org.neuroml.model](https://github.com/NeuroML/org.neuroml.model/blob/master/src/main/java/org/neuroml/model/util/hdf5/NeuroMLHDF5Writer.java). + +HDF5 NeuroML files can be read and processed by `jnml` and `pynml` in the same way as XML files (see [here](https://github.com/OpenSourceBrain/OpenCortex/tree/master/examples/HDF5) for LEMS Simulation file examples which reference HDF5 NeuroML models). diff --git a/_sources/Userdocs/ImportingMorphologyFiles.md b/_sources/Userdocs/ImportingMorphologyFiles.md new file mode 100644 index 00000000..ac21e131 --- /dev/null +++ b/_sources/Userdocs/ImportingMorphologyFiles.md @@ -0,0 +1,113 @@ +(userdocs:importing_morphology_files)= +# Handling Morphology Files + +A number of formats are used in neuroscience to encode neuronal morphologies obtained from experiments involving neuronal reconstructions. +This page provides general information on these formats, and documents how they may be converted to NeuroML 2 for use in computational models. + +(userdocs:importing_morphology_files:terminology)= +## Terminology + +```{figure} ../images/MorphologyNeuroML2.png +:alt: Morphologies in NeuroML 2. +:align: center + +Specification of morphologies in **NeuroML 2**. More details can be found for each element in the specification, e.g. {ref}` `, {ref}` `, {ref}` `, {ref}` `, {ref}` `, {ref}` `. +``` + +```{figure} ../images/crook2007-morphml-figure1.png +:alt: Figure 1 from {cite}`Crook2007` showing different representations of neuronal morphology. +:align: center +:width: 500px + +Figure 1 from {cite}`Crook2007`, a schematic comparing handling of morphological information for a simple cell by different applications. a) Schematic of biological cell structure to be represented. b) **Neurolucida reconstruction** where the soma is represented by an outline and three-dimensional points are specified along each branch. c) **NEURON simulator** format where cell structure is specified in _sections_. Only the center of the section is simulated unless the nseg parameter is greater than one. d) **GENESIS simulator representation** using compartments that are cylinders except for the soma, which can be spherical. The optimal length of each compartment is determined by the electrotonic length. e) **MorphML representation** (i.e. NeuroML v1) where any of the information shown in panels b through d can be encoded. +``` + +All formats have their own terminology that is used to refer to different parts of the cell. + +In [NEURON](https://neuronsimulator.github.io/nrn/python/modelspec/programmatic/topology/geometry.html): + +- a {code}`section` is an unbranched contiguous cell region +- the morphology of a cell is defined by 3D points, `pt3D` +- for simulation, one can specify how many segments a section should be divided into, given by {code}`nseg` + +In NeuroML: + +- segments are 3D points describing the cell morphology +- continuous, unbranched segments groups, would form a section +- the {code}`numberInternalDivisions` property can be used to set the number of divisions a segment or segment group should be divided into for simulation + +(userdocs:importing_morphology_files:validity)= +## Cell validity + +In general, it is usually necessary to examine NeuroML cells converted from various formats, especially experimental reconstructions, before they can be used in simulations. +This is because reconstructions may not always contain all the information necessary to simulate the cell. + +Two potential problems that must be checked are: + +- Point of connection of dendritic branches to the soma: e.g., in Neurolucida, there is no explicit soma but usually only an outline. +- Zero length sections: NEURON can work with zero segment lengths (consecutive `pt3d` points being equal), but a standard mapping of this may not be supported in other simulators such as GENESIS. + +An incomplete list of checks to make to ensure a valid cell is (taken from {ref}`neuroConstruct `): + +- Only one segment should be without a parent (root) +- All segments must have sections +- All segments must have endpoints +- All segments must have unique IDs +- All segments must have unique names +- All sections must have unique names +- Segments after the first in a section must only be connected to 1 parent +- Only one segment may be spherical and must belong to the {code}`soma_group` SegmentGroup +- The cell must have at least one segment +- The cell must have at least one soma section, i.e., which is in the {code}`soma_group` +- The cell must have a cell name + +The NeuroML validation tools will check for some of these and report errors where possible. + +(userdocs:importing_morphology_files:formats)= +## Formats + +(userdocs:importing_morphology_files:formats:neuron)= +### NEURON + +There is no fixed format in NEURON for specifying morphologies. +However, cells created in NEURON may be exported to NeuroML2 format using the [`export_to_neuroml2`](https://pyneuroml.readthedocs.io/en/stable/pyneuroml.neuron.html#pyneuroml.neuron.export_to_neuroml2) method included in {ref}`pyNeuroML ` ([example](https://github.com/OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes/blob/master/NeuroML2/export_nml2.py)). + +(userdocs:importing_morphology_files:formats:genesis)= +### GENESIS + +The format for a GENESIS cell description is given [here](http://www.genesis-sim.org/GENESIS/Hyperdoc/Manual-25.html#readcell). + +(userdocs:importing_morphology_files:formats:cvapp_swc)= +### CVapp (SWC files) + +The SWC format was developed to cover most of the information common between Neurolucida, NEURON, and GENESIS formats. +It is used by resources such as NeuroMorpho.org. + +Information on the SWC format can be found in the [NeuroMorpho FAQ](http://neuromorpho.org/myfaq.jsp) under the "What is SWC format" entry. + +A recommended application for converting SWC into NeuroML is neuroConstruct (see below). + +(userdocs:importing_morphology_files:formats:neurolucida)= +### Neurolucida + +The [Neurolucida](http://www.mbfbioscience.com/neurolucida) file format is used by MicroBrightField products to store information on neuronal reconstructions. +Both binary and ASCII format files can be generated by these products. +The format allows recording of various anatomical features, not only neuronal processes such as dendrites and cell bodies, but can record other micro-anatomical features of potential interest to anatomists. +Not all of these features will be relevant when constructing a single cell computational model. + +(userdocs:importing_morphology_files:tools)= +## Tools + +(userdocs:importing_morphology_files:tools:neuroconstruct)= +### neuroConstruct + +{ref}`neuroConstruct ` includes functionality to interactively import GENESIS, NEURON, CVapp (SWC), Neurolucida, and older MorphML formats to NeuroML2. +Please see the [neuroConstruct documentation](http://www.neuroconstruct.org/docs/import.html) for more information. + +Conversion of neuroConstruct's importing functions into pure Python for inclusion in {ref}`pyNeuroML ` [is a work in progress](https://github.com/NeuroML/pyNeuroML/issues/89). +Please contact us if you would like to help with this task. + +(userdocs:importing_morphology_files:tools:pyneuroml)= +### pyNeuroML + +{ref}`pyNeuroML ` includes functionality to convert NEURON files into NeuroML using the [`export_to_neuroml2`](https://pyneuroml.readthedocs.io/en/stable/pyneuroml.neuron.html#pyneuroml.neuron.export_to_neuroml2) method included in {ref}`pyNeuroML ` ([example](https://github.com/OpenSourceBrain/SmithEtAl2013-L23DendriticSpikes/blob/master/NeuroML2/export_nml2.py)). diff --git a/_sources/Userdocs/IzhikevichNetworkExample.md b/_sources/Userdocs/IzhikevichNetworkExample.md new file mode 100644 index 00000000..469c2533 --- /dev/null +++ b/_sources/Userdocs/IzhikevichNetworkExample.md @@ -0,0 +1,322 @@ +(userdocs:gettingstarted:izhikevichnetwork)= +# A two population network of regular spiking Izhikevich neurons + +Now that we have defined a cell, let us see how a network of these cells may be declared and simulated. +We will create a small network of cells, simulate this network, and generate a plot of the spike times of the cells (a raster plot): + + +```{figure} ../Userdocs/NML2_examples/example_izhikevich2007network_sim-spikes.png +:alt: Spike times of neurons recorded from the simulation +:align: center + +Spike times of neurons in 2 populations recorded from the simulation. +``` + +The Python script used to create the model, simulate it, and generate this plot is below. +Please note that this example uses the {ref}`NEURON ` simulator to simulate the model. +Please ensure that the `NEURON_HOME` environment variable is correctly set as noted {ref}`here `. + +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +---- +``` +As with the previous example, we will step through this script to see how the various components of the network are declared in NeuroML before running the simulation and generating the plot. +We will use the same helper functions to inspect the model as we build it: `component_factory`, `add`, `info`, `summary`. + + +(userdocs:gettingstarted:izhikevichnetwork:declaring)= +## Declaring the model in NeuroML + +To declare the complete network model, we must again first declare its core entities: +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 15-37 +---- +``` +Here, we create a new document, declare the {ref}`Izhikevich neuron`, and also declare the synapse that we are going to use to connect one population of neurons to the other. +We use the {ref}`ExpOne Synapse` here, where the conductance of the synapse increases instantaneously by a constant value `gbase` on receiving a spike, and then decays exponentially with a decay constant `tauDecay`. + +Let's inspect our model document so far: +``` +nml_doc.info(True) +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for NeuroMLDocument are: +... +* izhikevich2007_cells (class: Izhikevich2007Cell, Optional) + * Contents ('ids'/): ['iz2007RS0'] + +* ad_ex_ia_f_cells (class: AdExIaFCell, Optional) +* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional) +* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional) +* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional) +* pulse_generators (class: PulseGenerator, Optional) +* pulse_generator_dls (class: PulseGeneratorDL, Optional) +* id (class: NmlId, Required) + * Contents ('ids'/): IzNet + +* sine_generators (class: SineGenerator, Optional) +... +* IF_curr_exp (class: IF_curr_exp, Optional) +* exp_one_synapses (class: ExpOneSynapse, Optional) + * Contents ('ids'/): ['syn0'] + +* IF_cond_alpha (class: IF_cond_alpha, Optional) +* exp_two_synapses (class: ExpTwoSynapse, Optional) +... +``` +Let's also get a summary: +``` +print(nml_doc.summary()) +******************************************************* +* NeuroMLDocument: IzNet +* +* ExpOneSynapse: ['syn0'] +* Izhikevich2007Cell: ['iz2007RS0'] +* +******************************************************* +``` + +We can now declare our {ref}`network ` with 2 {ref}`populations ` of these cells. +Note: setting a color as a {ref}`property ` is optional, but is used in when we generate our plots below. +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 43-57 +---- +``` + +We can test to see if the network is now valid, since we have added the required populations to it: +``` +net.validate() +``` +This function does not return anything if the component is valid. +If it is invalid, however, it will throw a `ValueError`. + +We can now create {ref}`projections ` between the two populations based on some probability of connection. +To do this, we iterate over each post-synaptic neuron for each pre-synaptic neuron and draw a random number between 0 and 1. +If the drawn number is less than the required probability of connection, the connection is created. + +While we are iterating over all our pre-synaptic cells here, we also add external inputs to them using {ref}`ExplicitInputs ` +(this could have been done in a different loop, but it is convenient to also do this here). +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 62-101 +---- +``` + +Let us inspect our model again to confirm that we have it set up correctly. +``` +nml_doc.info(True) +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for NeuroMLDocument are: +* biophysical_properties (class: BiophysicalProperties, Optional) +* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional) +* cells (class: Cell, Optional) +* networks (class: Network, Optional) + * Contents ('ids'/): ['IzNet'] + +* cell2_ca_poolses (class: Cell2CaPools, Optional) +... +* izhikevich2007_cells (class: Izhikevich2007Cell, Optional) + * Contents ('ids'/): ['iz2007RS0'] + +* ad_ex_ia_f_cells (class: AdExIaFCell, Optional) +* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional) +* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional) +* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional) +* pulse_generators (class: PulseGenerator, Optional) + * Contents ('ids'/): ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4'] + +* pulse_generator_dls (class: PulseGeneratorDL, Optional) +* id (class: NmlId, Required) + * Contents ('ids'/): IzNet + +... +* exp_one_synapses (class: ExpOneSynapse, Optional) + * Contents ('ids'/): ['syn0'] + +* IF_cond_alpha (class: IF_cond_alpha, Optional) +.. + + +print(nml_doc.summary()) +******************************************************* +* NeuroMLDocument: IzNet +* +* ExpOneSynapse: ['syn0'] +* Izhikevich2007Cell: ['iz2007RS0'] +* PulseGenerator: ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4'] +* +* Network: IzNet +* +* 10 cells in 2 populations +* Population: IzPop0 with 5 components of type iz2007RS0 +* Properties: color=0 0 .8; +* Population: IzPop1 with 5 components of type iz2007RS0 +* Properties: color=.8 0 0; +* +* 20 connections in 1 projections +* Projection: proj from IzPop0 to IzPop1, synapse: syn0 +* 20 connections: [(Connection 0: 0 -> 0), ...] +* +* 0 inputs in 0 input lists +* +* 5 explicit inputs (outside of input lists) +* Explicit Input of type pg_0 to IzPop0(cell 0), destination: unspecified +* Explicit Input of type pg_1 to IzPop0(cell 1), destination: unspecified +* Explicit Input of type pg_2 to IzPop0(cell 2), destination: unspecified +* Explicit Input of type pg_3 to IzPop0(cell 3), destination: unspecified +* Explicit Input of type pg_4 to IzPop0(cell 4), destination: unspecified +* +******************************************************* + +``` +We can now save and validate our model. +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 105-110 +---- +``` +### The generated NeuroML model + +Let us take a look at the generated NeuroML model + +```{literalinclude} ./NML2_examples/izhikevich2007_network.nml +---- +language: xml +``` + +It should now be easy to see how the model is clearly declared in the NeuroML file. +Observe how entities are referenced in NeuroML depending on their location in the document architecture. +Here, {ref}`population ` and {ref}`projection ` are at the same level. +The synaptic connections using the {ref}`connection ` tag are at the next level. +So, in the {ref}`connection ` tags, populations are to be referred to as `../` which indicates the previous level. +The {ref}`explicitinput ` tag is at the same level as the {ref}`population ` and {ref}`projection ` tags, so we do *not* need to use `../` here to reference them. + +Another point worth noting here is that because we have defined a population of the same components by specifying a size rather than by individually adding components to it, we can refer to the entities of the population using the common `[..]` index operator. + + +The advantage of such a declarative format is that we can also easily get information on our model from the NeuroML file. +Similar to the `summary()` function that we have used so far, {ref}`pyNeuroML ` also includes the helper `pynml-summary` script that can be used to get summaries of NeuroML models from their NeuroML files: +```{code-block} console +$ pynml-summary izhikevich2007_network.nml +******************************************************* +* NeuroMLDocument: IzNet +* +* ExpOneSynapse: ['syn0'] +* Izhikevich2007Cell: ['iz2007RS0'] +* PulseGenerator: ['pulseGen_0', 'pulseGen_1', 'pulseGen_2', 'pulseGen_3', 'pulseGen_4'] +* +* Network: IzNet +* +* 10 cells in 2 populations +* Population: IzPop0 with 5 components of type iz2007RS0 +* Population: IzPop1 with 5 components of type iz2007RS0 +* +* 20 connections in 1 projections +* Projection: proj from IzPop0 to IzPop1, synapse: syn0 +* 20 connections: [(Connection 0: 0 -> 0), ...] +* +* 0 inputs in 0 input lists +* +* 5 explicit inputs (outside of input lists) +* Explicit Input of type pulseGen_0 to IzPop0(cell 0), destination: unspecified +* Explicit Input of type pulseGen_1 to IzPop0(cell 1), destination: unspecified +* Explicit Input of type pulseGen_2 to IzPop0(cell 2), destination: unspecified +* Explicit Input of type pulseGen_3 to IzPop0(cell 3), destination: unspecified +* Explicit Input of type pulseGen_4 to IzPop0(cell 4), destination: unspecified +* +******************************************************* + +``` + + +We can also generate a graphical summary of our model using `pynml` from {ref}`pyNeuroML `: +```{code-block} console +$ pynml izhikevich2007_network.nml -graph 3 +``` +This generates the following model summary diagram: +```{figure} ../Userdocs/NML2_examples/IzNet.gv.png +:alt: Model summary graph generated using pynml and the dot tool. +:align: center +:scale: 50% + +A summary graph of the model generated using pynml and the dot tool. +``` +Other options for `pynml` produce other views, e.g individual connections: +```{code-block} console +$ pynml izhikevich2007_network.nml -graph -1 +``` + +```{figure} ../Userdocs/NML2_examples/IzNet-1.gv.png +:alt: Model summary graph showing individual connections between cells in the populations. +:align: center +:scale: 70% + +Model summary graph showing individual connections between cells in the populations. +``` +In our very simple network here, neurons do not have morphologies and are not distributed in space. +In later examples, however, we will also see how summary figures of the network that show the morphologies, locations of different layers and neurons, and so on can also be generated using the NeuroML tools. + +(userdocs:gettingstarted:izhikevichnetwork:simulating)= +## Simulating the model + +Now that we have our model set up, we can proceed to simulating it. +We create our simulation, and setup the information we want to record from it. +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 112-137 +---- +``` +The generated LEMS file is here: +```{literalinclude} ./NML2_examples/LEMS_example_izhikevich2007network_sim.xml +---- +language: xml +``` + +Where we had generated a graphical summary of the model before, we can now also generate graphical summaries of the simulation using `pynml` and the `-lems-graph` option. This dives deeper into the LEMS definition of the cells, showing more of the underlying dynamics of the components: +```{code-block} console +$ pynml LEMS_example_izhikevich2007network_sim.xml -lems-graph +``` +Here is the generated summary graph: +```{figure} ../Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.png +:alt: Model summary graph generated using pynml. +:align: center +:scale: 50% + +A summary graph of the model generated using pynml -lems-graph. +``` +It shows a top-down breakdown of the simulation: from the network, to the populations, to the cell types, leading up to the components that these cells are made of (more on Components later). +Let us add the necessary code to run our simulation, this time using the well known NEURON simulator: +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 138-141 +---- +``` +(userdocs:gettingstarted:izhikevichnetwork:plotting)= +## Plotting recorded spike times +To analyse the outputs from the simulation, we can again plot the information we recorded. +In the previous example, we had recorded and plotted the membrane potentials from our cell. +Here, we have recorded the spike times. +So let us plot them to generate our figure: +```{literalinclude} ./NML2_examples/izhikevich-network.py +---- +language: python +lines: 143-162 +---- +``` +Observe how we are using the same `generate_plot` utility function as before: it is general enough to plot different recorded quantities. +Under the hood, it passes this information to Python's Matplotlib library. This produces the raster plot shown at the top of the page. + +This concludes our second example. +Here, we have seen how to create, simulate, and record from a simple two population network of single compartment point neurons. +The next section is an interactive notebook that you can use to play with this example. +After that we will move on to the next example: a neuron model using Hodgkin Huxley style ion channels. diff --git a/_sources/Userdocs/LEMS.md b/_sources/Userdocs/LEMS.md new file mode 100644 index 00000000..bc69bacd --- /dev/null +++ b/_sources/Userdocs/LEMS.md @@ -0,0 +1,114 @@ +(userdocs:lems)= +# LEMS: Low Entropy Model Specification + + +% from http://lems.github.io/LEMS/index.html + +A language for specifying hierarchical models based on fundamental physical relationships + +```{admonition} LEMS +:class: dropdown tip +For an in-depth guide to LEMS, please see the research paper: [LEMS: a language for expressing complex biological models in concise and hierarchical form and its use in underpinning NeuroML 2](https://www.frontiersin.org/articles/10.3389/fninf.2014.00079/full). Documentation on the structure of the LEMS language can be found {ref}`here `. +``` + +LEMS is being developed to provide a compact, minimally redundant, human-readable, human-writable, declarative way of expressing models of biological systems. + +It differs from other systems such as CellML or SBML in its requirement to be human writable and the inclusion of basic physical concepts such as dimensionality and physical nesting as part of the language. +The main goal is to enable model developers to write declarative models in LEMS in much the same way as software developers write software applications in computer languages such as in C, Java or Python. +The examples shown here use XML for expressing models as text, but LEMS is not primarily an XML language. Rather it defines a set of structures for representing models. The reference implementation also supports a more concise indentation-based format for representing models. + +There are two independent implementations of LEMS: jLEMS, written in Java and pyLEMS written in Python. +Both are hosted on the github.com/LEMS. + + +(userdocs:lems:capabilities)= +## Capabilities +You can define ComponentTypes (e.g. a "HH channel" or "a bi-exponential synapse") which express the general properties of a particular type of thing that goes in a model. +This includes saying what parameters they have, what child elements they are allowed, and how they behave (the equations). + +You can then define Components based on these types by supplying values for the parameters and adding any child elements that are required, so, for example, a bi-exponential synapse model with rise time 1ms and decay 5ms would be a component. + +ComponentTypes can extend other ComponentTypes to add extra parameters, fix certain values, and otherwise modify their behavior. +Components can extend other Components to reuse specified parameter values. +There is also a loose notion of abstract types, so a component can accept children with a particular lineage without needing to know exactly what type they are. +This can be used, for example, to define cells that accept synaptic connections provided they have a particular signature. + +Each ComponentType can have a Dynamics element that specifies how it behaves: what the state variables are, the equations that govern them, and what happens when events are sent or received. +The interpreter takes a model consisting of type and component elements referenced from a network, builds an instance from them and runs it. + +For those familiar with object oriented languages, the ComponentType/Component distinction is close to the normal Class/Instance distinction. +When the model is run, the same pattern applies again, with the Components acting as class definitions, with their "instances" actually containing the state variables in the running mode. + + +(userdocs:lems:background)= +## Background + +The March 2010 NeuroML meeting ([minutes](https://docs.neuroml.org/_static/files/NeuroMLWorkshop2010.pdf)) identified a need to extend the capability within NeuroML for expressing a range of models of synapses. +It was decided that the hitherto adopted approach of defining parameterized building blocks to construct models by combining blocks and setting parameters was unlikely to be flexible enough to cope with the needs for synapse models. +This is not obvious a-priori, since, for example, the pre NeuroML 2.0 ion channel building blocks are fully adequate to describe the dynamics of a wide range existing channel models. +But there appears to be no such commonality in models used for synapses, where the mechanisms used range from highly detailed biochemical models to much more abstract ones. + +This work also has antecedents in Catacomb 3, which was essentially a GUI for a component definition system and model builder using a type system similar to that proposed here. +Much of the XML processing code used in the interpreter was taken from PSICS which itself currently uses the "building block" approach to model specification. +The need for user-defined types has been considered with respect to future PSICS development, and this proposal also reflects potential requirements for PSICS. + +(userdocs:lems:example)= +## Example + +Here is the XML for a simple integrate-and-fire cell definition: + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +Once this definition is available, a particular model using this structure can be specified with the following XML: + +```{code-block} xml + +``` + +More complex models will have nested components and other types of parameters, but the basic principle of separating out the equations and parameters for reusable model components, such that the equations are only stated once, remains the same. diff --git a/_sources/Userdocs/LEMSExample1.md b/_sources/Userdocs/LEMSExample1.md new file mode 100644 index 00000000..f5f0a541 --- /dev/null +++ b/_sources/Userdocs/LEMSExample1.md @@ -0,0 +1,377 @@ +(userdocs:lemsexample1)= +# Example 1: Dimensions, Units, ComponentTypes and Components + +This page is structured as a walk-through of a single example explaining the various elements as they occur. + +```{literalinclude} ./LEMS_examples/example1.xml +---- +language: xml +---- +``` + +The whole model is wrapped in a block which, for now, is called "Lems" (Low Entropy Model Specification). Then we define the dimensions that will be used in this model. Typically these would be loaded from an external file along with various other stuff, not repeated in each model, but it is included here in the interests of having a single file for everything. + +```{code-block} xml + + + + + + +``` +Each dimension element just associates a dimension name with the exponents for mass, length, time and current. + +At this stage, one can begin defining component types. +This is done with the ComponentType element and child Parameter elements. +A simple cell model with three parameters could be defined as: + +```{code-block} xml + + + + + +``` +Each of the Parameter elements defines a parameter that should be supplied when a component is defined based on this type. +Before we can define a component though, we need some units to use in setting those values. + +Defining a unit involves supplying the symbol, dimension and the power of ten by which it is scaled from the IS base unit. +Note that units have a symbol, not a name. +This is because they occur as a component of an assignment expression such as 'threshold="-45mV"' not as a reference such as 'dimension="voltage"'. In general, where one component refers to another, then the attribute value is the name of the thing being referred to, and the attribute name is the lower case version of the type of the thing being referred to. +Thus when a dimension is declared with then it is referred to from a Parameter as . This holds for all references to components of a particular type. + +Returning to the units, this model will use the following, which normally would also be loaded from an external file of standard settings. + +```{code-block} xml + + + + + + + + + +``` +Once the units are available it is possible to define a component. +There are two equivalent ways of doing this: either by using the Component element and setting its type, or by using the type as a new XML element. +The latter may be a little more readable, but for a simple component like this it doesn't make much difference. +For more complicated components with nested children though, the second form is definitely clearer (eg see the HHChannel examples later). + + +```{code-block} xml + + +``` + +In specifying a component, a value must be supplied for each of the parameters defined in the corresponding type. +The value is composed of a number and a unit. +It can't include expressions with multiple units for the values so, for example, to express an acceleration you couldn't write "3 m s^-2". Instead would need to define a unit element for the compound unit (and a dimension element for acceleration) and use that. + +Specifying all the parameters for each component can lead to duplication. +Suppose, for example, you want to build a range of cell models all based on cell1, but you don't want to change the threshold. +You could define a new type without the threshold, but it is neater to still use the same type but specify that you are restricting attention to the set that all have a particular value for the threshold. +This can be done by creating a new type that extends the cell1 type and includes a Fixed element to fix the threshold: + +```{code-block} xml + + + +``` + +The cell2 type can now be used by only setting the remaining two parameters. + +As well as restricting types when you extend them, you can also add new parameters as shown in the next type. +This also introduces an EventPort, to indicate that instances of components built from this type can receive events, and, finally, a Dynamics block. +This is where the Dynamics of instances of the component can be specified. +The phrase "instances of the component" is intentional. +The type itself doesn't "behave": it is just a definition. +A component built from the type doesn't "behave" either: it is just a set of parameter values linked back to the type. +The thing that "behaves" is an instance in a runnable model that actually contains state variables. +In general, many components may be based on one type, and one component may give rise to many instances in a running model. + +Here is a basic capacitative cell with a leaking potential and a simple event handler. + +```{code-block} xml + + + + + + + + + + + + + + +``` + +The Dynamics involves a single state variable, a voltage called "v", and one equation, expressing how v drifts towards the leak reversal potential. +The event block specifies what happens when an instance receives an event. +In this case the state variable v is bumped up by deltaV. The value attribute in the TimeDerivative element is an expression involving the parameters and the state variables. +It gives the right hand side of a first order differential equation dv/dt = (...). Expressions follow normal operator precedence rules with "^" for general powers and exp(x) for exponentials. + +Below is another example of a Dynamics, this time with an output port and a condition testing block that sends an event when the condition becomes true. +The test attribute in the OnCondition element is a boolean valued expression. +These use Fortran style operators (.gt. and .lt. for > and <) to avoid confusion with xml angle brackets. + +```{code-block} xml + + + + + + + + + + + + + +``` + +The above model is one way of writing a regular event generator. +It has a state variable that grows in sync with t until it reaches a threshold when the event fires and it is reset. +The model below achieves the same effect without solving a differential equation. +Instead, it asks for access to the global time variable ("t" is the one global variable that is always available) and uses that in the test condition. +[aside - there's a slight problem here since t exists even if the model doesn't define a dimension called time]. + +```{code-block} xml + + + + + + + + + + + +``` + +The examples so far have all been of very simple components which just had a single set of parameters. +Real models however require rather more structure than this with components having children of various types and possibly multiple children of certain types. +To illustrate this, the next example shows how the concept of an ion channel using Hodgkin-Huxley Dynamics can be defined. + +Starting from the bottom, we define the different types of rate equations that occur. +These will supply terms in the equations for the derivatives of the gating particles. +There are three different expressions used in the HH equations, but they can all be expressed with three parameters, rate, midpoint and scale. +We first define a general rate class, and then extend it for the three cases. + +The HHRate Dynamics shows two new constructs. +An Exposure declares that the component makes a quantity available to other components. +A Requirement specifies that the component needs to know about a variable that it doesn't define itself. +When it is used in a model, the specified variable must be available (and have the right dimension) in the parent component or one of its more remote ancestors. + +Note that the general HHRate class defines an Exposure without a Dynamics block to actually set its value. +This is analogous to an abstract class in java: you can't actually make a component out of the HHRate element directly (the interpreter will complain) but any component using a HHRate will know it has an exposed variable called "r". The types that extend HHRate have to supply a value for "r" before they are fully defined and ready to be used. + +So here is the basic HHRate and its three extensions: + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + +``` +Now the rate elements are available, they can be used to define a component for a gate in a HH model. +This introduces the Child element which says that components built using this type must include a subcomponent of the specified type. +A HH gate needs subcomponents for the forward and reverse rates. + +```{code-block} xml + + + + + + + + + + + + + + +``` +The above is a perfectly reasonable way to define a HH gate but unfortunately it needs smarter numerics than the simple forward Euler rule used in the proof of concept interpreter. +Running this model with the Euler method leads to numerical instabilities. +Happily, this problem can be circumvented without improving the numerics by changing the state variable. +Instead of q which is defined on [0, 1] you can use x defined on (-infinity, infinity) which works much better with a naive integration scheme. +This is what it looks like with x instead of q: + +```{code-block} xml + + + + + + + + + + + + + + + + +``` +Now the gate type has been defined, it can be used to say what a HH Channel actually is. +In this picture, a channel just has a conductance and one or more gates: + +```{code-block} xml + + + + + + + + + + +``` +This introduces one new construct, the Children element, that allows for an indeterminate number of children of a given type. +This means that the same type can be used for potassium channels with only one gate, sodium channels with two gates or indeed other channels with more gates. +The first derived variable in the Dynamics block uses a xpath-style selection function to process the indeterminate number of children. +In this case it computes the produce of the fcond variables from the different gates. + +With these definitions in place, it is now possible to define some channel models. +The classic Hodgkin-Huxley sodium channel can be represented as: + + +```{code-block} xml + + + + + + + + + + +``` +The potassium channel uses exactly the same types, but has only one gate: + + +```{code-block} xml + + + + + + +``` +These channel models are an example where the ability to use the type name as the XML tag makes the model much clearer: the alternative just with three levels of Component elements would look rather unhelpful. + +Although the channel models have now been defined, they still need to be used in a cell before anything can be run. +For this we'll just define a basic channel population type. +There is one new construct here: the ComponentRef element which in this case says that a channel population needs a reference to a component of type HHChannel. This is much like a Child element, but instead of the component being defined then and there inside the channel population, there is just a reference to it. + +The Dynamics block for a cannel population just computes the total conductance and then the current, in this case using Ohm's law. + +```{code-block} xml + + + + + + + + + + + + +``` +To use these populations, they need inserting in a cell. +The following type represents a simple cell with a number of populations and an option to inject a current so it does something interesting. + +```{code-block} xml + + + + + + + + + + + + + + + +``` +This Dynamics block introduces the OnStart element which is much like the OnEvent elements earlier, except the block applies only when the simulation starts. +In this case it just sets the voltage to a value supplied as a parameter. +The Dynamics block uses another selector function "sum(..." to sum the currents delivered by the various populations. + +Now all the definitions are in place to define a cell model with a couple of channel populations: + + +```{code-block} xml + + + + +``` + +To go with this cell type, we can define some components using the other types defined earlier. +Note how celltype_d is based on an existing component via the "extends" attribute and only replaces one parameter value. + + +```{code-block} xml + + + + + +``` +Finally a simulation element says what component is to be run and for how long. +It also contains an embedded display element so the results of the simulation can be visualized. +These are also user-defined types: their definitions will be presented in example 6. + +```{code-block} xml + + + + + +``` +That's it. When this model is run it produces the figure shown below (after rescaling a bit). + +```{figure} ../Userdocs/LEMS_examples/lems_example4.png +:alt: LEMS GUI showing simulation output graphs +:align: center + +LEMS GUI showing simulation output graphs +``` + diff --git a/_sources/Userdocs/LEMSExample2.md b/_sources/Userdocs/LEMSExample2.md new file mode 100644 index 00000000..16e8ab85 --- /dev/null +++ b/_sources/Userdocs/LEMSExample2.md @@ -0,0 +1,90 @@ +(userdocs:lemsexample2)= +# Example 2: tidying up example 1 + +This models is the same as in example 1, except that the definitions have been split out into several self-contained files. + +The main file, included below, uses the Include element to include definitions from other files. +Each file is only read once, even if several files include it. +Because some of these files, such as the HH channel definitions, are intended to be used on their own, they include all the dimension definitions they need. +These may also occur in other files with the same dimension names. +This is fine as long as the dimensions being declared are the same. +An error will be reported if a new definition is supplied that changes any of the values. +The same applies for Unit definitions. +For other element types names and ids must be unique. +An id or name can't appear twice, even if the content of the elements is the same. + +# Main model +This defines a few components, then a network that uses them and a simulation to run it all. The HHCell component refers to channel types coming from the included hhmodels.xml file which in turn depends on hhcell.xml and hhchannel.xml. +```{literalinclude} ./LEMS_examples/example2.xml +---- +language: xml +---- +``` + +# Included files + +```{literalinclude} ./LEMS_examples/ex2dims.xml +---- +language: xml +---- +``` + +The file hhchannel.xml contains complete definitions of a fairly general HH-style channel model with any number of gates based on the three standard types used in the original HH work. + + +```{literalinclude} ./LEMS_examples/hhchannel.xml +---- +language: xml +---- +``` +As mentioned in example1, the numerics are too feeble to cope with this gate definition though, so a change of variables is employed instead: + +```{literalinclude} ./LEMS_examples/hhaltgate.xml +---- +language: xml +---- +``` + +The file hhcell.xml defines a simple cell model with some populations of HH channels. + + +```{literalinclude} ./LEMS_examples/hhcell.xml +---- +language: xml +---- +``` + +A couple of spike generators. + +```{literalinclude} ./LEMS_examples/spikegenerators.xml +---- +language: xml +---- +``` + +And now the components themselves. +These are the standard HH sodium and potassium channels (as used in Rallpack3). + + +```{literalinclude} ./LEMS_examples/hhmodels.xml +---- +language: xml +---- +``` + +Some miscellaneous iaf models. + +```{literalinclude} ./LEMS_examples/misciaf.xml +---- +language: xml +---- +``` + +Finally, a small collection of dimension definitions useful for things like the miscellaneous iaf cell definitions. + + +```{literalinclude} ./LEMS_examples/elecdims.xml +---- +language: xml +---- +``` diff --git a/_sources/Userdocs/LEMSExample3.md b/_sources/Userdocs/LEMSExample3.md new file mode 100644 index 00000000..3ab1056f --- /dev/null +++ b/_sources/Userdocs/LEMSExample3.md @@ -0,0 +1,17 @@ +(userdocs:lemsexample3)= +# Example 3: Connection dependent synaptic components + +In many models, a synapse is only created where a connection exists. +This means that the model of the receiving cell should only declare that particular types of synapse can be added to it, not the actual synapse sub-components themselves. + +Not much is needed beyond the elements described in example 1 except for some extensions to the component that declares the connectivity and a new child element in the component that the synapses are attached to. +The full example is shown below. +The synapse type includes an EventPort just like the previously defined cell type. +The cell type however includes a new child element: Attachments defined as: + +```{code-block} xml + +``` + +This operates rather like the Children element except that when a component is defined using this type the sub-elements are not included in the component definition. +Instead it indicates that instances of components of the particular type may be attached later when the model is actually run. diff --git a/_sources/Userdocs/LEMSExample4.md b/_sources/Userdocs/LEMSExample4.md new file mode 100644 index 00000000..1362ee36 --- /dev/null +++ b/_sources/Userdocs/LEMSExample4.md @@ -0,0 +1,190 @@ +(userdocs:lemsexample4)= +# Example 4: Kinetic schemes + +The existing components provide everything necessary to define types that allow a model to specify a kinetic scheme (Markov model). +The missing ingredient is the Dynamics element to actually expresses how instances of the components develop through time. + +First then, the following definitions can be used to express ion channel models where the channel state is represented by an occupancy vector among a number of distinct states with rates for the transitions between states. + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +This says that a gate can contain any number of states and transitions. +A state has an occupancy variable, and a transition has links to two states giving the source and target states for the transition. + +The transition element here is an abstract element because it doesn't provide a Dynamics block but just specifies what quantities transitions should privide via the two exposures. +One of the most useful forms of transition is a damped Boltzman equation which can be parameterizd as follows: + +```{code-block} xml + + + + + + + + + + + + + + + +``` + +Given these definitions, we can express a couple of simple channel models that use kinetic schemes. +There is nothing special about these models. +They are just examples used in PSICS that produce spikes (albeit rather unnatural looking ones) when used together. + +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +This has all been done with the existing components. +They allow types to be defined for expressing kinetic schemes, and models can be expressed that use these types, but there is nothing so far that says that the model actually is governed by a kinetic scheme. +In particular, there is an "occupancy" state variable in each state element for which there is no governing equation and the rates generate "rf" and "rr" quantities that are not unused anywhere. + +What is needed is a new element in the Dynamics block to link these together and say that the rates apply to the changes of occupancy among the state elements. +This is done by adding a KineticScheme element to the Dynamics block for a gate as follows (this now shows the full definition of the KSGate element): + +```{code-block} xml + + + + + + + + + + + + + + + +``` +The new part here is the KineticScheme element and its children Nodes, Edges and Tabulable. +The Nodes element says which elements in the parent container are goverened by the scheme, and which variable in those elements represents the relative occupancy. + +The Edges element is a little more complicated. +It has to say not only which elements define the transitions, but how the fields in the transitions map to things the scheme knows about. +For a transition in a kinetic scheme, you need to know which state the transition comes from, which it goes to, and how fast it goes. +It is possible (as here) that a single transition defines both directions, in which case it must also say which variable in the target objects provides the reverse transition rates. +This is what the last four attributes of the Edges element do. + +The Tabulable element is a temporary convenience for implementation purposes. +In this case it says that the rates depend only on v and that the transition matrices can be cached an reused on a grid of spacing deltaV rather than recomputed every time. +This is not used in the 0.2.1 version of the interpreter. + +Note that the KineticScheme element doesn't say anything about what the outputs are. +All it does is control the occupancy state variable in the state elements. +The interpretation of these quantities is specified in the normal way with the two DerivedVaraible declarations. +No special elements are needed in the scheme itself. + +To actually use these models we need cell and population elements to link them all together. +There is nothing new here - it all works just as for HH channels. +The rest of the example4.xml file is: + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +When run, this produces: + +```{figure} ../Userdocs/LEMS_examples/lems_example4.png +:alt: LEMS GUI showing simulation output graphs +:align: center + +LEMS GUI showing simulation output graphs +``` + +There are clearly some initialization issues but the basic Dynamics is the same as the PSICS version of this model. diff --git a/_sources/Userdocs/LEMSExample5.md b/_sources/Userdocs/LEMSExample5.md new file mode 100644 index 00000000..9cd1adc7 --- /dev/null +++ b/_sources/Userdocs/LEMSExample5.md @@ -0,0 +1,96 @@ +(userdocs:lemsexample5)= +# Example 5: References and paths + +The ChannelPopulation type used earlier repeats a common model specification error in that it makes the reversal potential of a population of channels a parameter of the population (often it is made a parameter of the channel specification, which is equally bad): + +```{code-block} xml + + + + + +``` +In fact, of course, the reversal potential is not a property of a channel population, or of a channel. +It depends on the environment the channel is put in and the ions it is permeable to. +But, it is needed in the Dynamics specification for the population so just putting it in as a parameter solves the immediate problem. +In the process, however, it introduces the potential for easily creating contradictory models, by, for example setting different reversals for populations of the same type of channel. + +A much better approach is to let the channel just say what it is permeable to. +Some other element in the model can define the membrane reversal potentials for different channels, and the channel population object should then look up the relevant value for the permeant ion of its channel. +This provides a cleaner expression of what is there, removes redundancy and lowers the entropy of the model specification. + +The following three types are sufficient to provide a simple framework to centralize the definitions of species and reversal potentials on one place: + +```{code-block} xml + + + + + + + + + + + +``` +Once these are available, they can be used to define some species, and to create an environment component that sets their reversal potentials: + +```{code-block} xml + + + + + + + +``` +The next step is to add a species reference to the channel type, so that channel definitions can say what species they are permeant to. + +```{code-block} xml + + + + + + + + + +``` +Finally the channel population type needs modifying to add a derived parameter that addresses the reversal potential from the membrane properties: + +```{code-block} xml + + + + + + + + + + + +``` +This introduces a new construct, the DerivedParameter specification that defines a local parameter "erev" to hold the quantity from the specified path: + +```{code-block} xml + +``` + +The path here uses XPath like syntax operating on the component tree in the model. +In this case, it finds all the elements of thpe MembranePotential in the model. +The predicate selects the one for which the species is the same as the species referred to from the channel used for this population. +Finally, it takes the "reversal" parameter from the membrane potential component. +This is made locally available as the parameter "erev". + +The Dynamics of this model is exactly the same as example 4. +The full model including both the type definitions and the components is included below. + + +```{literalinclude} ./LEMS_examples/example5.xml +---- +language: xml +---- +``` diff --git a/_sources/Userdocs/LEMSExample6.md b/_sources/Userdocs/LEMSExample6.md new file mode 100644 index 00000000..64e13b85 --- /dev/null +++ b/_sources/Userdocs/LEMSExample6.md @@ -0,0 +1,76 @@ +(userdocs:lemsexample6)= +# Example 6: User defined types for simulation and display + +Up until now, the examples have used a set of simple Simulation, Display and Line constructs without explaining how they are defined. +This shows what is needed in the Dynamics block to let the user defined types to specify that they actually define a runnable simulation or settings that can be used to display results. + +This means that the user can select their own names for the different parameters required for a simulation, and, more importantly, simulation and display attributes can be added to existing type definitions to make multi-faceted type definitions that can both be run on their own or as part of a larger simulation. + +Example 6 shows two new elements that can be used in the Dynamics block, Run and Show as illustrated in the following user-defined type that defines a simulation: + +```{code-block} xml + + + + + + + + + + + +``` +The 'component' attribute of the Run element specifies which parameter of the type contains the reference to the component that should actually be run. +The 'step' and 'increment' attributes specify the parameters that hold the timestep and total runtime. +The 'variable' attribute is for future use - at present, the independent variable is always 't'. + +A Run element can be added to the Dynamics block in any type definition to make it independently runnable. + +Running a simulation without any output is rarely much use, so there are two futher elements that can be included in the Dynamics block: Show and Record. +The 'src' attribute of the Show element points to the components that should be shown. +These in turn can contain other Show elements but eventually everything pointed to by a Show element should contain one or more Record elements. +These specify what will actually be sent as output. +They have the path to the variable as the 'quantity' attribute, its scale as the 'scale' attribute and the line color for plotting. + +The following two types show one way that these can be combined to allow the user to express a display object containing one or more lines. + +```{code-block} xml + + + + + + + + + + + + + + + +``` +Once these have been defined, a component can be constructed that uses them as follows: + + +```{code-block} xml + + + + + + + +``` +When run, this produces the output shown below: + +```{figure} ../Userdocs/LEMS_examples/lems_example6.png +:alt: LEMS GUI showing simulation output graphs +:align: center + +LEMS GUI showing simulation output graphs +``` + +Note how the scale attributes are set to 1mV and 1nS for the different lines so that they show up on the same axes. diff --git a/_sources/Userdocs/LEMSExample7.md b/_sources/Userdocs/LEMSExample7.md new file mode 100644 index 00000000..12c7d9eb --- /dev/null +++ b/_sources/Userdocs/LEMSExample7.md @@ -0,0 +1,104 @@ +(userdocs:lemsexample7)= +# Example 7: User defined types for networks and populations + +This example shows how the standard component type structures can be used to declare components for simple networks. +The following three definitions allow networks to be constructed containing fixed size populations of a particular component type. + +```{code-block} xml + + + + + + + + + + + + + +``` +The harder part is to provide elements in the Dynamics blocks to express what should be done with components based on these types. +The Network element doesn't pose any problems because the default behavior on instantiation will do the right thing: it will instantiate each of the child populations and EventConnectivity elements. + +But the population element needs to say that its instantiation involves making 'size' instances of the component referred to by the 'component' reference, where 'size' is the value supplied for the size parameter in a component specification. +This can be done by including a Build element inside the Dynamics block: + +```{code-block} xml + + + + + + + + + +``` +The MultiInstantiate specification says that there should be 'size' instances of the component referred to in the 'component' parameter created when the model is built. +This overrides the default behavior. +[TODO: what is the Build element content corresponding to the default behavior?]. + +This serves to create some rather simple populations. +More complex specifications, such as putting one instance at each point of a grid satisfying a particular constraint could be handled via first declaring elements to form the grid, and then using selectors that pick the points in the population element to actually put the cells at [its not clear to me how much more would be required to make this work, other than implementing proper xpath-like selectors]. + +The following three types define a general connectivity structure with an abstract ConnectionPattern type, and a specific instance for All-All connectivity. + +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +The Build element in the AllAll pattern uses a new ForEach construct and the EventConnectin element from before. +The ForEach element operates selects each instance matching its 'instances' attribute, and applies the enclosing directives, much in the same way as for-each in XSL. +The proof of concept interpreter also has Choose, When and Otherwise elements that operate much like their XSL equivalents, although these are not used in this example. + +With these definitions in place, a network simulation can be defined with the following: + + +```{code-block} xml + + + + + + + + + + + + + + +``` +The output when the model is run is shown below, followed by the full listing. + +```{figure} ../Userdocs/LEMS_examples/lems_example7.png +:alt: LEMS GUI showing simulation output graphs +:align: center + +LEMS GUI showing simulation output graphs +``` + +```{literalinclude} ./LEMS_examples/example7.xml +---- +language: xml +---- +``` diff --git a/_sources/Userdocs/LEMSExample8.md b/_sources/Userdocs/LEMSExample8.md new file mode 100644 index 00000000..5a133839 --- /dev/null +++ b/_sources/Userdocs/LEMSExample8.md @@ -0,0 +1,56 @@ +(userdocs:lemsexample8)= +# Example 8: Regimes in Dynamics definitions + +This example introduces the Regime, Transition and OnEntry elements within a Dynamics block. +Rather than having a single state instance, the entity can be on one of the defined regimes at any given time. +The Transition element occurring inside a condition block serves to move it from one regime to another. +The OnEntry block inside a regime can contain initialization directives that apply each time the entity enters that regime. + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +Full listing: +```{literalinclude} ./LEMS_examples/example8.xml +---- +language: xml +---- +``` diff --git a/_sources/Userdocs/LEMSOverview.md b/_sources/Userdocs/LEMSOverview.md new file mode 100644 index 00000000..cbf0aae3 --- /dev/null +++ b/_sources/Userdocs/LEMSOverview.md @@ -0,0 +1,181 @@ +(userdocs:lemsoverview)= +# Model structure overview + +% http://lems.github.io/LEMS/introduction.html + +Models are based on user-defined types (the term ComponentType is used in the XML) that contain parameter declarations, reference declarations and specification of what children an instance of a type can have. +Typically they also contain a Dynamics specification which can contain build-time and run-time declarations. +Build-time declarations apply when a simulation is set up, for example to connect cells. +Run-time declarations specify the state variables, equations and events that are involved. + +An instance of a ComponentType is a model Component It specifies a particular set of parameters for a given ComponentType. It says nothing about state variables: in a simulation, typically many run-time instances will correspond to a single model component definition, and several model component definitions will use the same type. +A run-time instance holds its own set of state variables as defined by the Type definition and a reference to its component for the parameter values specific to that particular model component. +The update rules come from the type definition. +As such, neither the ComponentType nor the Component is properly a "prototype" for the runtime instance. + +(userdocs:lemsoverview:defining_component_types)= +## Defining ComponentTypes + +ComponentTypes are declared as, for example: + +```{code-block} xml + + + +``` + +A Component based on such a type is expressed as: + +```{code-block} xml + +``` + +The quoted value for 'threshold' here is a rich quantity with size and dimensions, typically consisting of a numerical value and a unit symbol. +Assignments like this are the only place unit symbols can occur. +Equations and expressions relate rich types, independent of any particular unit system. + +An equivalent way of writing the above in shorthand notation (using an example of a string with size and dimension for threshold) is: + +```{code-block} xml + +``` + +A type can contain elements for specifying the following aspects of the structure and parameters of a model component: + +- Parameter - dimensional quantities that remain fixed within a model +- Child - a required single sub-component of a given type +- Children - variable number of sub-components of the given type +- ComponentRef - a reference to a top-level component definition. +- Link - a reference to a component definition relative to the referrer +- Attachments - for build-time connections +- EventPort - for run-time discrete event communication +- Exposure - quantities that can be accessed from other components +- Requirement - quantities that must be accessible to the component for it to make sense +- DerivedParameter - like parameters, but derived from some other quantity in the model + +The "EventPort" and "Attachments" declarations don't have any corresponding elements in their model component specification. +They only affect how the component can be used when a model is instantiated. +EventPorts specify that a model can send or receive events, and should match up with declarations in its Dynamics specification. +An "Attachments" declaration specifies that a run-time instance can have dynamically generated attachments as, for example, when a new synapse run-time instance is added to a cell for each incoming connection. + +(userdocs:lemsoverview:inheritance)= +## Inheritance + +A type can extend another type, adding new parameters, or supplying values (SetParam) for inherited parameters. +As well as reducing duplication, the key application of this is with the Child and Children declarations, where a type can specify that it needs a child or children of a particular supertype, but doesn't care about which particular sub-type is used in a model. +This applies, for example, where a cell requires synapses that compute a quantity with dimensions current, but doesn't need access to any other parts of the synapse Dynamics. + +(userdocs:lemsoverview:runtime_dynamics)= +## Run-time Dynamics +Run time Dynamics are included within a Dynamics block in a type specification. +They include declaration of: + +- state variables +- first order differential equations with respect to time of state variables +- derived quantities - things computed in terms of other local quantities or computed from other run-time instances + +Run time Dynamics can be grouped into Regimes, where only one regime is operative at a given time for a particular run-time instance. +Regimes have access to all the variables in the parent instance and can define their own local variables. + +Dynamics can also contain event blocks: + +- OnStart blocks contain any initialization declarations needed when a run-time state is instantiated +- OnEvent blocks specify what happens when an event is received on a specified port +- OnEntry blocks (only within regimes) specify things that should happen each time the system enters that regime. +- OnCondition blocks have a test condition and specify what should happen when it is met. + +Blocks may contain state variable assignments, event sending directives and transition directives to indicate that the system should change from one regime to another. + +(userdocs:lemsoverview:buildtime_structure)= +## Build-time Structure +Build-time Structure defines the structure of a multi-component model. +Currently there are: + +- MultiInstantiate - for declaring that a component yields multiple run-time instances corresponding to a particular model component. Eg, for defining populations of cells. +- ForEach - for iterating over multiple instances in the run-time structure +- EventConnection - for connecting ports between run-time instances + +(userdocs:lemsoverview:other)= +## Other + +There are also Run, Show and Record Dynamics for creating type definitions that define simulations and what should be recorded or displayed from such a simulation. + +(userdocs:lemsoverview:observations)= +## Observations +The numerous references to "run-time instances" above is problematic, since the structures do not dictate any particular way of building a simulator or running a model. +In particular, there is no requirement that a component or Dynamics declaration should give rise to any particular collection of state variables that could be interpreted as a run-time instance in the state of a simulator. + +So, it is convenient to think of eventual state instances, and that is indeed how the reference interpreter works, but the model specification structure should avoid anything that is specific to this picture. + +(userdocs:lemsoverview:typespecific_examples)= +## Type specification examples +Examples of type definitions using the various types of child element: + +```{code-block} xml + + + +``` +says that instances of components using this type can receive events. +```{code-block} xml + + + +``` +says that a HHChannel can have gates. +```{code-block} xml + + + + +``` +says that a HHGate has two children called Forward and Reverse, each of type HHRate. +```{code-block} xml + + + +``` +says that instances of components based on the synapseCell type can have instances of component based on the synapse type attached to them at build time. +```{code-block} xml + + + +``` +says that components based on the Population type need a reference to a component of type Component (ie, anything) (which would then be used as the thing to be repeated in the population, but it doesn't say that here). +```{code-block} xml + + + +``` +says that EventConnectivity components need a relative path to a local component of type Population which will be accessed via the name "source". +The model component declarations corresponding to the channel and gate types would be: + +```{code-block} xml + + + + + + +``` +or, in the shorthand notation: + +```{code-block} xml + + + + + + +``` +For the population type it would be: + + +```{code-block} xml + +``` +And for the connections: + +```{code-block} xml + +``` diff --git a/_sources/Userdocs/LEMSSchema.md b/_sources/Userdocs/LEMSSchema.md new file mode 100644 index 00000000..f7cd50e5 --- /dev/null +++ b/_sources/Userdocs/LEMSSchema.md @@ -0,0 +1,31 @@ +(userdocs:lemsschema)= +# LEMS + +The current version of the LEMS specification is 0.7.6 and the schema for this can be seen [here](https://github.com/LEMS/LEMS/blob/master/Schemas/LEMS/LEMS_v0.7.6.xsd). +The following figure, taken from Cannon et al. 2014 ({cite}`Cannon2014`) shows the structure of LEMS models. +The following pages give details of all the elements that are included in LEMS. +For examples on LEMS, and using LEMS to extend NeuroML, please see the relevant sections in the documentation. + +```{figure} ../images/lems-figure2.png +:alt: Structure of LEMS models +:align: center +:width: 80% + +*(A)* Models in LEMS are specified using ComponentType definitions with nested +Dynamics elements. Any Parameter or StateVariable declaration must refer to a +Dimension element defined at the top level. A Component element sets parameter +values for a particular instance of a ComponentType. Each Parameter value must +refer to one of the Unit elements defined at the top level. The Dynamics +element supports continuous time systems defined in terms of first order +differential equations, and event driven processing as specified by the various +"On. . ." elements. Multiple Regimes, each with independent TimeDerivative +expressions can be defined, along with the rules to transition between them. +*(B)* Example of a ComponentType, the passive channel model from Figure 1. +*(C)* The XML equivalent of the ComponentType (top) and Component (bottom) for this +model. *(D)* Defining containment in LEMS, using Child (exactly one sub element +of the given type) or Children (zero or multiple copies). **(E)** Extension in +LEMS. Extending ComponentTypes inherit the structure of the base type. Example +Components in XML are shown in *(D,E)*. + +``` + diff --git a/_sources/Userdocs/LEMSSimulation.md b/_sources/Userdocs/LEMSSimulation.md new file mode 100644 index 00000000..2776ee1d --- /dev/null +++ b/_sources/Userdocs/LEMSSimulation.md @@ -0,0 +1,66 @@ +(userdocs:lemssimulation)= +# LEMS Simulation files + +For many users, the most obvious place that LEMS is used is in the LEMS Simulation file (usually {ref}`LEMS_*.xml `). + +In short, what a file like this does is: + +- point at the NeuroML file containing the model to simulate +- include any other LEMS file it needs, including the {ref}`NeuroML core type definitions ` +- specify how long to run the simulation for and the simulation timestep (dt) +- say what to display when the simulation has finished (e.g. membrane potentials of selected cells) +- say what to save to file, e.g. voltage traces, spike times + +These files are crucial in many of the workflows for {ref}`simulating NeuroML models `, and are reused across different simulator targets, e.g. `jnml LEMS_MyNetwork.xml` (run in jNeuroML), `jnml LEMS_MyNetwork.xml -neuron` (convert to NEURON), `jnml LEMS_MyNetwork.xml -brian2` (convert to Brian2). See {ref}`here ` for more information. + +```{figure} ../images/lems_nml_files.png +:alt: LEMS Simulation file and NeuroML file +:align: center +:scale: 24 % + +Typical organisation for a NeuroML simulation. The main NeuroML model is specified in a file with the network (`*.net.nml`), which can include/point to files containing individual synapses (`*.synapse.nml`) or cell files (`*.cell.nml`). If the latter are conductance based, they may include external channel files (`*.channel.nml`). The main LEMS Simulation file only needs to include the network file, and tools for running simulations of the model refer to just this LEMS file. Exceptions to these conventions are frequent and simulations will run perfectly well with all the elements inside the main LEMS file, but using this scheme will maximise reusability of model elements. + +``` + +## Specification of format + +See {ref}`here ` for definition of the main elements used in the file, including {ref}`schema:display`, {ref}`schema:outputfile`, etc. + +## Quantities and paths + +Specifying the quantities to save/display in a LEMS Simulation file is an important and sometimes confusing process. There is a {ref}`dedicated page ` on quantities and paths in LEMS and NeuroML2. + +## Creating LEMS Simulation files + +Perhaps the easiest way to create a LEMS Simulation file is to base it off of an existing example. + +```{literalinclude} ./NML2_examples/lems_sim/LEMS_SimulationExample.xml +---- +language: xml +``` + +Alternatively, it is possible to create a LEMS Simulation file in Python file using pyNeuroML: + +```{literalinclude} ./NML2_examples/lems_sim/create_lems.py +---- +language: python +``` + +See [this example](https://github.com/NeuroML/pyNeuroML/blob/master/examples/create_new_lems_file.py) for more details. + +## What about SED-ML? + +The Simulation Experiment Description Markup Language ([SED-ML](https://sed-ml.org/)) is used by a number of other initiatives such as SBML for specifying simulation setup, execution and basic analysis. + +We chose to have a LEMS specific format for specifying simulations in NeuroML2 as opposed to natively supporting SED-ML, mainly because of the tight link to the LEMS language and {ref}`jLEMS ` package, i.e. all of the NeuroML2 elements and elements in a LEMS simulation file have underlying definitions in the LEMS language. However it is possible to convert the LEMS simulation to the equivalent in SED-ML. + +### Exporting LEMS simulation descriptions to SED-ML + + +```{code-block} console +# Using jnml +jnml -sedml + +# Using pynml +pynml -sedml +``` diff --git a/_sources/Userdocs/LEMS_elements/DefiningComponents.md b/_sources/Userdocs/LEMS_elements/DefiningComponents.md new file mode 100644 index 00000000..817269cc --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/DefiningComponents.md @@ -0,0 +1,46 @@ + +(lemsschema:page:defining_components_)= +# Defining Components + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:component_)= +## Component + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**id**$ String$ +**name**$ String$ Name by which the component was declared - this shouldn't be accessible. +**declaredType**$ String$ Name by which the component was declared - this shouldn't be accessible. +**type**$ String$ +**eXtends**$ String$ + +``` +```` + +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**insertions**$ {ref}`lemsschema:insertion_` +**components**$ {ref}`lemsschema:component_` +**abouts**$ {ref}`lemsschema:about_` +**metas**$ {ref}`lemsschema:meta_` + +``` +```` +````` \ No newline at end of file diff --git a/_sources/Userdocs/LEMS_elements/Definingcomponenttypes.md b/_sources/Userdocs/LEMS_elements/Definingcomponenttypes.md new file mode 100644 index 00000000..d4e54ae0 --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Definingcomponenttypes.md @@ -0,0 +1,489 @@ + +(lemsschema:page:defining_component_types_)= +# Defining component types + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:componenttype_)= +## ComponentType + +Root element for defining LEMS Component Types. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name of the component type. This can be uses as an XML element name in the shorthand form whendefining components. +**eXtends**$ String$ The component type that this type inherits field definitions for, if any + +``` +```` + +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**parameters**$ {ref}`lemsschema:parameter_` +**indexParameters**$ {ref}`lemsschema:indexparameter_` +**derivedParameters**$ {ref}`lemsschema:derivedparameter_` +**pathParameters**$ {ref}`lemsschema:pathparameter_` +**requirements**$ {ref}`lemsschema:requirement_` +**componentRequirements**$ {ref}`lemsschema:componentrequirement_` +**instanceRequirements**$ {ref}`lemsschema:instancerequirement_` +**exposures**$ {ref}`lemsschema:exposure_` +**childs**$ {ref}`lemsschema:child_` +**childrens**$ {ref}`lemsschema:children_` +**links**$ {ref}`lemsschema:link_` +**componentReferences**$ {ref}`lemsschema:componentreference_` +**componentTypeReferences**$ {ref}`lemsschema:componenttypereference_` +**locations**$ {ref}`lemsschema:location_` +**propertys**$ {ref}`lemsschema:property_` +**dynamicses**$ {ref}`lemsschema:dynamics_` +**structures**$ {ref}`lemsschema:structure_` +**simulations**$ {ref}`lemsschema:simulation_` +**equilibriums**$ {ref}`lemsschema:equilibrium_` +**procedures**$ {ref}`lemsschema:procedure_` +**geometrys**$ {ref}`lemsschema:geometry_` +**fixeds**$ {ref}`lemsschema:fixed_` +**constants**$ {ref}`lemsschema:constant_` +**attachmentses**$ {ref}`lemsschema:attachments_` +**eventPorts**$ {ref}`lemsschema:eventport_` +**paths**$ {ref}`lemsschema:path_` +**texts**$ {ref}`lemsschema:text_` +**collections**$ {ref}`lemsschema:collection_` +**pairCollections**$ {ref}`lemsschema:paircollection_` +**abouts**$ {ref}`lemsschema:about_` +**metas**$ {ref}`lemsschema:meta_` + +``` +```` +````` +(lemsschema:parameter_)= +## Parameter + +A quantity, defined by name and dimension, that must be supplied when a Component of the enclosing ComponentType is defined + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name of the parameter. This is the name of the attribute to be used when the parameter is supplied in a component definition +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the parameter + +``` +```` +````` +(lemsschema:pathparameter_)= +## PathParameter + +A parameter of which the value is a path expression. When a ComponentType declares a PathParameter, a corresponding Component definition should have an attibute with that name whose value is a path expression that evaluates within the instance tree of the built model. This is used, for example, in the definition of a group component class, where the coresponding component specifies a path over the instance tree which selectesthe items that should go in the group. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the parameter + +``` +```` +````` +(lemsschema:property_)= +## Property + +An property on an instance of a component. Unlike a Parameter, a Property can very from instance to instance. It should be set with an Assign element within the build specification. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ +**dimension**$ String$ +**defaultValue**$ String$ The defaultValue for the property must be a plain number (no units) giving the SI magnitude of the quantity. + +``` +```` +````` +(lemsschema:derivedparameter_)= +## DerivedParameter + +A parameter that is a function of the Component's Parameters, which does not change with time. Its value can be supplied either with the 'value' attribute that evaluates within the scope of the definition, or with the 'select' attribute which gives a path to 'primary' version of the parameter. For example, setting select='//MembranePotential[species=channel/species]/reversal' within the appropriate context allows a channel's reversal potential to taken from a single global setting according to its permeant ion, rather than explicitly supplied locally. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name of the derived parameter +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the derived parameter +**select**$ String$ Path to the parameter that supplies the value. Exactly one of 'select' and 'value' is required. +**value**$ String$ A string defining the value of the element + +``` +```` +````` +(lemsschema:fixed_)= +## Fixed + +Fixes the value of a parameter in the parent class, so that it does not have to be supplied separately in component definitions. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**parameter**$ String$ +**value**$ String$ + +``` +```` +````` +(lemsschema:requirement_)= +## Requirement + +A Requirement gives the name and dimension of a quantity (parameter or variable) that should be accessible within the scope of a model component. This is only applicable for elements that can be included as children of other elements, where the scope comprises its own parameters and those in the scope of its enclosing element. Once a requirement has been declared, then the quantity can be used within the Dynamics definition of the component. It is the responsibility of an implementation to check that the component is only used in a context in which the requirement is met. A typical example is in defining membrand bound components which require access to the membrane potential but where the variable that holds the potential itself is defined in the top level component. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ name +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the requirement + +``` +```` +````` +(lemsschema:componentrequirement_)= +## ComponentRequirement + +The name of a component or component reference that must exist in the component hierarchy + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ name + +``` +```` +````` +(lemsschema:instancerequirement_)= +## InstanceRequirement + +An instance that must be supplied at build time. Expressions can contain references to quantities in the instance + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ name + +``` +```` +````` +(lemsschema:exposure_)= +## Exposure + +A quantity that is made available to other components in the simulation. Note that all variables in a Dynamics definition are private. If other components need access to them, then the definition should explicitly link them to an exposure defined in the component class + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the exposure element +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the element + +``` +```` +````` +(lemsschema:child_)= +## Child + +Specifies that a component can have a child of a particular type. The name supplied here can be used in path expressions to access the component. This is useful, for example, where a component can have multiple children of the same type but with different roles, such as the forward and reverse transition rates in a channel. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the child +**type**$ String$ Reference to a component class, the value should be the name of the target class. +**description**$ String$ An optional description of the child + +``` +```` +````` +(lemsschema:children_)= +## Children + +Specifies that a component can have children of a particular class. The class may refer to an extendedtype, in which case components of any class that extends the specified target class should be valid as child components + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the children +**type**$ String$ The class of component allowed as children. + +``` +```` +````` +(lemsschema:link_)= +## Link + +Like a ComponentRef, but resolved relative to the enclosing object so the target must already be in the model. One or the other should be deprecated. The Link element has the same properties as ComponentRef. The Link element just establishes a connection with the target component, but leaves it in its existing place in the hierarchy. Variables in the target component can be accessed via the name of the link element. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ A name for the ComponentReference +**type**$ String$ The type of the target Component +**description**$ String$ An optional description of the ComponentReference + +``` +```` +````` +(lemsschema:componentreference_)= +## ComponentReference + +A reference to another component. The target component can be accessed with path expressions in the same way as a child component, but can be defined independently + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ A name for the ComponentReference +**type**$ String$ The type of the target Component +**description**$ String$ An optional description of the ComponentReference + +``` +```` +````` +(lemsschema:componenttypereference_)= +## ComponentTypeReference + +This is used in conjunction with PathParameter elements to specify the target class of selections defined within components operating over the instance tree. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ + +``` +```` +````` +(lemsschema:collection_)= +## Collection + +Specifies that instances of components based on this class can containe a named collection of other instances. This provides for containers for oprating on groups of instances with path and filter expressions defined in components to operate over the instance tree. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ + +``` +```` +````` +(lemsschema:paircollection_)= +## PairCollection + +Defines a named collection of paris of instances, similar to the Collection element. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ + +``` +```` +````` +(lemsschema:eventport_)= +## EventPort + +A port on a component that can send or receive events, depending on the direction specified + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the EventPort +**direction**$ String$ 'IN' or 'OUT' +**description**$ String$ An optional description of the EventPort + +``` +```` +````` +(lemsschema:text_)= +## Text + +Holds textual information that does not change the model but is needed for other purposes such as labelling graphs. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The textual content +**description**$ String$ An optional description of the element + +``` +```` +````` +(lemsschema:path_)= +## Path + +Duplicates some functionality of PathParameter - the two should be merged. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ + +``` +```` +````` +(lemsschema:attachments_)= +## Attachments + +Specifies that a component can accept attached components of a particular class. Attached components can be added at build time dependent on other events. For scoping and access purposes they are like child components. The cannonical use of attachments is in adding synapses to a cell when a network connection is made. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ A name for the Attachments +**type**$ String$ The type of the Attachments + +``` +```` +````` +(lemsschema:insertion_)= +## Insertion + + + + +(lemsschema:integerparameter_)= +## IntegerParameter + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name of the parameter. This is the name of the attribute to be used when the parameter is supplied in a component definition +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the parameter + +``` +```` +````` +(lemsschema:indexparameter_)= +## IndexParameter + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name of the parameter. This is the name of the attribute to be used when the parameter is supplied in a component definition +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the parameter + +``` +```` +````` +(lemsschema:about_)= +## About + + + + +(lemsschema:meta_)= +## Meta + +Meta element to provide arbitrary metadata to LEMS simulations. Note that this is not processed by the LEMS interpreter. + diff --git a/_sources/Userdocs/LEMS_elements/Dynamics.md b/_sources/Userdocs/LEMS_elements/Dynamics.md new file mode 100644 index 00000000..01bc22ac --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Dynamics.md @@ -0,0 +1,366 @@ + +(lemsschema:page:dynamics_)= +# Dynamics + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:dynamics_)= +## Dynamics + +Specifies the dynamical behavior of components build from this ComponentType. Note that all variables in a Dynamics definition are private. If other components need access to them, then the definition should explicitly link them to an Exposure defined in the component class + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**supers**$ {ref}`lemsschema:super_` +**derivedVariables**$ {ref}`lemsschema:derivedvariable_` +**conditionalDerivedVariables**$ {ref}`lemsschema:conditionalderivedvariable_` +**stateVariables**$ {ref}`lemsschema:statevariable_` +**timeDerivatives**$ {ref}`lemsschema:timederivative_` +**kineticSchemes**$ {ref}`lemsschema:kineticscheme_` +**onStarts**$ {ref}`lemsschema:onstart_` +**onEvents**$ {ref}`lemsschema:onevent_` +**onConditions**$ {ref}`lemsschema:oncondition_` +**stateScalarFields**$ {ref}`lemsschema:statescalarfield_` +**derivedScalarFields**$ {ref}`lemsschema:derivedscalarfield_` +**derivedPunctateFields**$ {ref}`lemsschema:derivedpunctatefield_` +**regimes**$ {ref}`lemsschema:regime_` + +``` +```` +````` +(lemsschema:statevariable_)= +## StateVariable + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the state variable +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**exposure**$ String$ If this variable is to be accessed from outside, it should be linked to an Exposure that is defined in the ComponentType. +**description**$ String$ An optional description of the state variable + +``` +```` +````` +(lemsschema:stateassignment_)= +## StateAssignment + +Has 'variable' and 'value' fields + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**variable**$ String$ The name of the variable +**value**$ String$ A string defining the value of the element + +``` +```` +````` +(lemsschema:timederivative_)= +## TimeDerivative + +First order differential equations, functions of StateVariables and Parameters, for how StateVariables change with time. Has a variable and a value. The value is the rate of change of the variable. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**variable**$ String$ The name of the variable +**value**$ String$ A string defining the value of the element + +``` +```` +````` +(lemsschema:derivedvariable_)= +## DerivedVariable + +A quantity that depends algebraically on other quantities in the model. The 'value' field can be set to a mathematical expression, or the 'select' field to a path expression. If the path expression produces multiple matches, then the 'reduce' field says how these are reduced to a single value by taking the sum or product. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of the derived variable +**select**$ String$ A path to the variable that supplies the value. Note that to select a variable from another component, the variable must be marked as an Exposure. Exactly one of 'select' and 'value' is required +**dimension**$ String$ The dimension, or 'none'. This should be the name of an already defined dimension element +**description**$ String$ An optional description of the derived variable +**reduce**$ String$ Either 'add' or 'multiply'. This applies if ther are multiple matches to the path or if 'required' is false. In the latter case, for multiply mode, multiplicative expressions in this variable behave as if the term was absent. Additive expressions generate an error. Conversely, if set to 'add' then additive expressions behave as if it was not there and multiplicative ones generateand error. +**exposure**$ String$ +**required**$ boolean$ Set to true if it OK for this variable to be absent. See 'reduce' for what happens in this case +**value**$ String$ A string defining the value of the element + +``` +```` +````` +(lemsschema:onstart_)= +## OnStart + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**stateAssignments**$ {ref}`lemsschema:stateassignment_` +**eventOuts**$ {ref}`lemsschema:eventout_` +**transitions**$ {ref}`lemsschema:transition_` + +``` +```` +````` +(lemsschema:oncondition_)= +## OnCondition + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**stateAssignments**$ {ref}`lemsschema:stateassignment_` +**eventOuts**$ {ref}`lemsschema:eventout_` +**transitions**$ {ref}`lemsschema:transition_` + +``` +```` +````` +(lemsschema:onevent_)= +## OnEvent + +Event handler block + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**port**$ String$ the port to listen on + +``` +```` + +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**stateAssignments**$ {ref}`lemsschema:stateassignment_` +**eventOuts**$ {ref}`lemsschema:eventout_` +**transitions**$ {ref}`lemsschema:transition_` + +``` +```` +````` +(lemsschema:eventout_)= +## EventOut + + + + +(lemsschema:kineticscheme_)= +## KineticScheme + +Allows the specification of systems that can be in one of a small number of states at any time with probabilistic transitions between states. This includes continuous time Markov processes as are used for stochastic models of ion channels. A kinetic scheme does not itself introduce any new elements or state variables. It is rather a way of connecting quantities in existing components by saying that quantities in the edge elements should be interpreted as transition rates among quantities in the node elements. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ Name of kinetic scheme +**nodes**$ String$ Source of notes for scheme +**edges**$ String$ The element that provides the transitions for the scheme +**stateVariable**$ String$ Name of state variable in state elements +**edgeSource**$ String$ The name of the attribute in the rate element that defines the source of the transition +**edgeTarget**$ String$ Attribute tha defines the target +**forwardRate**$ String$ Name of forward rate exposure +**reverseRate**$ String$ Name of reverse rate exposure + +``` +```` +````` +(lemsschema:regime_)= +## Regime + +Allows the dynamics of a ComponentType to be expressed via a finite state machine. Each regime has its internal dynamics, and conditions on which transitions between regimes occur are specified using the OnCondition element + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name of the regime +**initial**$ String$ 'True' if this is the initial regime of the system + +``` +```` + +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**derivedVariables**$ {ref}`lemsschema:derivedvariable_` +**stateVariables**$ {ref}`lemsschema:statevariable_` +**timeDerivatives**$ {ref}`lemsschema:timederivative_` +**onStarts**$ {ref}`lemsschema:onstart_` +**onEntrys**$ {ref}`lemsschema:onentry_` +**onEvents**$ {ref}`lemsschema:onevent_` +**onConditions**$ {ref}`lemsschema:oncondition_` +**requiredVars**$ {ref}`lemsschema:requiredvar_` + +``` +```` +````` +(lemsschema:onentry_)= +## OnEntry + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**stateAssignments**$ {ref}`lemsschema:stateassignment_` +**eventOuts**$ {ref}`lemsschema:eventout_` +**transitions**$ {ref}`lemsschema:transition_` + +``` +```` +````` +(lemsschema:transition_)= +## Transition + + + + +(lemsschema:super_)= +## Super + + + + +(lemsschema:conditionalderivedvariable_)= +## ConditionalDerivedVariable + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ +**dimension**$ String$ +**exposure**$ String$ + +``` +```` + +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**cases**$ {ref}`lemsschema:case_` + +``` +```` +````` +(lemsschema:case_)= +## Case + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**value**$ String$ A string defining the value of the element + +``` +```` +````` +(lemsschema:equilibrium_)= +## Equilibrium + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**derivedVariables**$ {ref}`lemsschema:derivedvariable_` + +``` +```` +````` +(lemsschema:statescalarfield_)= +## StateScalarField + + + + +(lemsschema:derivedscalarfield_)= +## DerivedScalarField + + + + +(lemsschema:derivedpunctatefield_)= +## DerivedPunctateField + + + diff --git a/_sources/Userdocs/LEMS_elements/Geometry.md b/_sources/Userdocs/LEMS_elements/Geometry.md new file mode 100644 index 00000000..7260663d --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Geometry.md @@ -0,0 +1,70 @@ + +(lemsschema:page:geometry_)= +# Geometry + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:geometry_)= +## Geometry + +Specifies the geometrical interpretation of the properties of components realizing this ComponentType. + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**frustums**$ {ref}`lemsschema:frustum_` +**solids**$ {ref}`lemsschema:solid_` +**skeletons**$ {ref}`lemsschema:skeleton_` + +``` +```` +````` +(lemsschema:frustum_)= +## Frustum + + + + +(lemsschema:solid_)= +## Solid + + + + +(lemsschema:location_)= +## Location + + + + +(lemsschema:skeleton_)= +## Skeleton + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**scalarFields**$ {ref}`lemsschema:scalarfield_` + +``` +```` +````` +(lemsschema:scalarfield_)= +## ScalarField + + + diff --git a/_sources/Userdocs/LEMS_elements/Modelstructure.md b/_sources/Userdocs/LEMS_elements/Modelstructure.md new file mode 100644 index 00000000..9aca0a51 --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Modelstructure.md @@ -0,0 +1,92 @@ + +(lemsschema:page:model_structure_)= +# Model structure + +**Models can be spread over multiple files. The root element in each file is Lems.** + +--- + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:lems_)= +## Lems + +Root element for any lems content + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**dimensions**$ {ref}`lemsschema:dimension_` +**constants**$ {ref}`lemsschema:constant_` +**units**$ {ref}`lemsschema:unit_` +**assertions**$ {ref}`lemsschema:assertion_` +**componentTypes**$ {ref}`lemsschema:componenttype_` +**components**$ {ref}`lemsschema:component_` +**targets**$ {ref}`lemsschema:target_` + +``` +```` +````` +(lemsschema:target_)= +## Target + +A lems file can contain many component definitions. A Target elements specifies that a components should be treated as the entry point for simulation or other processing + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**component**$ String$ Reference to the entry point component +**reportFile**$ String$ Optional attribute specifying file in which to save short report of simulation +**timesFile**$ String$ Optional attribute specifying file in which to save times used in simulation + +``` +```` +````` +(lemsschema:constant_)= +## Constant + +A constant quantity: like a parameter for which the value is supplied in the class definition itself rather than when a component is defined. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ A readable name for the constant. +**symbol**$ String$ The symbol used in expressions to refer to this constant. +**value**$ String$ The value of a constant must be a plain number (no units) giving the SI magnitude of the quantity or an expression involving only plain numbers or other constants. +**dimension**$ String$ + +``` +```` +````` +(lemsschema:include_)= +## Include + +Include LEMS files in other LEMS files. Files are included where the Include declaration occurs. The enclosing Lems block is stripped off and the rest of the content included as is + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**file**$ String$ the name or relative path of a file to be included + +``` +```` +````` \ No newline at end of file diff --git a/_sources/Userdocs/LEMS_elements/Procedure.md b/_sources/Userdocs/LEMS_elements/Procedure.md new file mode 100644 index 00000000..dd57197d --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Procedure.md @@ -0,0 +1,56 @@ + +(lemsschema:page:procedure_)= +# Procedure + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:procedure_)= +## Procedure + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**statements**$ {ref}`lemsschema:statement_` + +``` +```` +````` +(lemsschema:equilibrate_)= +## Equilibrate + + + + +(lemsschema:foreachcomponent_)= +## ForEachComponent + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**statements**$ {ref}`lemsschema:statement_` + +``` +```` +````` +(lemsschema:print_)= +## Print + + + diff --git a/_sources/Userdocs/LEMS_elements/Simulation.md b/_sources/Userdocs/LEMS_elements/Simulation.md new file mode 100644 index 00000000..14a8af65 --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Simulation.md @@ -0,0 +1,108 @@ + +(lemsschema:page:simulation_)= +# Simulation + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:simulation_)= +## Simulation + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**records**$ {ref}`lemsschema:record_` +**eventRecords**$ {ref}`lemsschema:eventrecord_` +**runs**$ {ref}`lemsschema:run_` +**dataDisplays**$ {ref}`lemsschema:datadisplay_` +**dataWriters**$ {ref}`lemsschema:datawriter_` +**eventWriters**$ {ref}`lemsschema:eventwriter_` + +``` +```` +````` +(lemsschema:record_)= +## Record + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**quantity**$ String$ path to the parameter that will contain the path to the quantity to be recorded +**scale**$ String$ path to the element that defines the scale for rendering the quantity dimensionless +**color**$ String$ hex format color suggestion for how the data should be displayed + +``` +```` +````` +(lemsschema:eventrecord_)= +## EventRecord + + + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**quantity**$ String$ path for the component which will emit spikes to be recorded +**eventPort**$ String$ event port for the component which will emit spikes + +``` +```` +````` +(lemsschema:datadisplay_)= +## DataDisplay + + + + +(lemsschema:datawriter_)= +## DataWriter + + + + +(lemsschema:eventwriter_)= +## EventWriter + + + + +(lemsschema:run_)= +## Run + +The run element provides a way to make a model runnable. It should point to the parameters that set the step size etc. The target parameters have to be dimensionally consistent. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**component**$ String$ name of the component reference that will set the component to be run +**variable**$ String$ +**increment**$ String$ path to the parameter that sets the step size +**total**$ String$ path to the parameter that sets the total span of the independent variable to be run + +``` +```` +````` \ No newline at end of file diff --git a/_sources/Userdocs/LEMS_elements/Structure.md b/_sources/Userdocs/LEMS_elements/Structure.md new file mode 100644 index 00000000..fbbe5f57 --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Structure.md @@ -0,0 +1,311 @@ + +(lemsschema:page:structure_)= +# Structure + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:structure_)= +## Structure + +By default, each Component in a model gives rise to a single instance of its state variables when the model is executed. The state variables are then governed by the dynamics definition in the associated ComponentType. Elements in the Structure declaration can be used to change this behavior, for example to make multiple instances of the state variables, or to instantiate a different component. A typical application for the latter would be a Component that defines a population of cells. The population Component might define the number of cells it contains but would refer to a Component defined elsewhere for the actual cell model to use. + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:buildelement_)= +## BuildElement + +Base class for elements that can be used in Structures + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:multiinstantiate_)= +## MultiInstantiate + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**assigns**$ {ref}`lemsschema:assign_` +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:coinstantiate_)= +## CoInstantiate + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**assigns**$ {ref}`lemsschema:assign_` +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:assign_)= +## Assign + + + + +(lemsschema:choose_)= +## Choose + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:childinstance_)= +## ChildInstance + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**assigns**$ {ref}`lemsschema:assign_` +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:foreach_)= +## ForEach + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:eventconnection_)= +## EventConnection + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**assigns**$ {ref}`lemsschema:assign_` +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:tunnel_)= +## Tunnel + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**assigns**$ {ref}`lemsschema:assign_` +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:pairseventconnection_)= +## PairsEventConnection + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:pairfilter_)= +## PairFilter + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:includepair_)= +## IncludePair + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:with_)= +## With + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:if_)= +## If + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:apply_)= +## Apply + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:gather_)= +## Gather + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` +(lemsschema:gatherpairs_)= +## GatherPairs + + + +`````{tab-set} +````{tab-item} can contain these elements +```{csv-table} +:widths: 2, 8 +:width: 100% +:delim: $ + +**buildElements**$ {ref}`lemsschema:buildelement_` + +``` +```` +````` \ No newline at end of file diff --git a/_sources/Userdocs/LEMS_elements/Unitsanddimensions.md b/_sources/Userdocs/LEMS_elements/Unitsanddimensions.md new file mode 100644 index 00000000..fe9917da --- /dev/null +++ b/_sources/Userdocs/LEMS_elements/Unitsanddimensions.md @@ -0,0 +1,75 @@ + +(lemsschema:page:units_and_dimensions_)= +# Units and dimensions + + + +Generated on 22/08/23. +Please file any issues or questions at the [issue tracker here](https://github.com/LEMS/LEMS/issues). + +--- + +(lemsschema:dimension_)= +## Dimension + +A Dimenson element associated a name with a particular combination of the standards SI base dimensions, mass, lenght, time, current, temperature and amount if substance (moles). Fractional dimensions are not currently supported. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ The name to be used when referring to this dimension from variable declaration or units +**m**$ int$ Mass +**l**$ int$ Length +**t**$ int$ Time +**i**$ int$ Current +**k**$ int$ Temperature +**n**$ int$ Amount of substance +**j**$ int$ Luminous intensity + +``` +```` +````` +(lemsschema:unit_)= +## Unit + +A Unit asociates a symbol with a dimension and a power of ten. For non-metric units a scale can be provided, as in '1 inch = 0.0254 m'. In this case there is a degeneracy between the power and the scale which is best resolved by not using the two together. The offset parameter is available for units which are not zero-offset, such as farenheit. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**name**$ String$ As with constants, units are only referred to within expressions using their symbols, so the name is just for readability. +**symbol**$ String$ The symbol is used to refer to this unit inside compound expressions coutaining a number and a unit symbol. Such expressions can only occur on the right hand side of assignments statements. +**dimension**$ String$ Reference to the dimension for this unit +**power**$ int$ Power of ten +**scale**$ double$ Scale, only to be used for scales which are not powers of ten +**offset**$ double$ Offset for non zero-offset units + +``` +```` +````` +(lemsschema:assertion_)= +## Assertion + +Assertions are not strictly part of the model, but can be included in a file as a consistency check. + +`````{tab-set} +````{tab-item} Properties +```{csv-table} +:widths: 1, 2, 7 +:width: 100% +:delim: $ + +**dimension**$ String$ The name of a dimension +**matches**$ String$ An expression involving dimensions. The dimensionality of the expression should match the dimensionality of the dimension reference. + +``` +```` +````` \ No newline at end of file diff --git a/_sources/Userdocs/MissionAndAims.md b/_sources/Userdocs/MissionAndAims.md new file mode 100644 index 00000000..b4a47874 --- /dev/null +++ b/_sources/Userdocs/MissionAndAims.md @@ -0,0 +1,19 @@ +(missions_and_aims)= +# Mission and Aims + +Computational models, based on detailed neuroanatomical and electrophysiological data, are heavily used as an aid for understanding the nervous system. +NeuroML is an international, collaborative initiative to develop a language for describing detailed models of neural systems, which will serve as a +standard data format for defining and exchanging descriptions of neuronal cell and network models. + +NeuroML specifications are developed by the {ref}`NeuroML Editorial Board ` and overseen by its {ref}`Scientific Committee `. +NeuroML is [endorsed by the INCF](https://www.incf.org/sbp/neuroml), and is also an official [COMBINE standard](http://co.mbine.org/standards/neuroml). + +The NeuroML project community develops an [XML (eXtensible Markup Language)](https://wikipedia.org/XML) based description language where [XML Schemas](https://www.w3schools.com/xml/schema_intro.asp) are used to define model specifications. +The community also develops and maintains a number of libraries (in {ref}`Python, Java and other languages `) to facilitate use of these specifications. + +The **aims of the NeuroML initiative** are: + +- To create specifications for an XML-based language that describes the biophysics, anatomy and network architecture of neuronal systems at multiple scales +- To facilitate the exchange of complex neuronal models between researchers, allowing for greater transparency and accessibility of models +- To promote software tools which support NeuroML and support the development of new software and databases for neural modeling +- To encourage researchers with models within the scope of NeuroML to exchange and publish their models in this format diff --git a/_sources/Userdocs/MultiCompartmentOLMexample.md b/_sources/Userdocs/MultiCompartmentOLMexample.md new file mode 100644 index 00000000..a26c72b7 --- /dev/null +++ b/_sources/Userdocs/MultiCompartmentOLMexample.md @@ -0,0 +1,455 @@ +(userdocs:getting_started:multi_compartment_example)= +# Simulating a multi compartment OLM neuron + +In this section we will model and simulate a multi-compartment Oriens-lacunosum moleculare (OLM) interneuron cell from the rodent hippocampal CA1 network model developed by Bezaire et al. ({cite}`Bezaire2016`). +The complete network model can be seen [here on GitHub](https://github.com/mbezaire/ca1), and [here on Open Source Brain](https://www.opensourcebrain.org/projects/nc_ca1). + +```{figure} ../Userdocs/NML2_examples/olm.cell.xy.png +:alt: Morphology of constructed OLM cell in xy plane +:align: center +:width: 50% + +Morphology of OLM cell in xy plane +``` +```{figure} ../Userdocs/NML2_examples/olm_example_sim_seg0_soma0-v.png +:alt: Membrane potential for neuron recorded from the simulation at the soma +:align: center +:width: 50% + +Membrane potential of the simulated OLM cell at the soma. +``` +This plot, saved as `olm_example_sim_seg0_soma0-v.png` is generated using the following Python NeuroML script: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +---- +``` +## Declaring the model in NeuroML + +Similar to previous examples, we will first declare the model, visualise it, and then simulate it. +The OLM model is slightly more complex than the HH neuron model we had worked with in the {ref}`previous tutorial ` since it includes multiple compartments. +However, where we had declared the ion-channels ourselves in the previous example, here will will not do so. +We will *include* channels that have been pre-defined in NeuroML to demonstrate how components defined in NeuroML can be easily re-used in models. + +We will follow the same method as before. +We will first define the cell, create a network with one instance of the cell, and then simulate it to record and plot the membrane potential from different segments. + +### Declaring the cell + +To keep our Python script modularised, we start constructing our {ref}`cell ` in a separate function. +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 111-290 +---- +``` +Let us walk through this function: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 116-123 +---- +``` +We create a new model document that will hold the cell model. +Then, we create and add a new {ref}`Cell ` using the `add` method to the document. +We also provide a `neuro_lex_id` here, which is the [NeuroLex ontology identifier](https://scicrunch.org/scicrunch/interlex/view/ilx_0105030?searchTerm=oriens-lacunosum%20moleculare). +This allows us to better connect models to biological concepts. + +As we have seen in the {ref}`single Izhikevich neuron example `, the `add` method calls the `component_factory` to create the component object for us. +For the `Cell` component type, it does a number of extra things for us to set up, or initialise, the cell. + +We have a number of ways of inspecting the cell. +The `summary` function provides a very short summary of the cell. +This is useful to quickly get a high level overview of it: +```pycon +>>> cell.summary() +******************************************************* +* Cell: olm +* Notes: None +* Segments: 0 +* SegmentGroups: 4 +******************************************************* +``` +We can also use the general {ref}`info function ` to inspect the cell: +```pycon +>>> cell.info(show_contents=True) +Cell -- Cell with **segment** s specified in a **morphology** element along with details on its **biophysicalProperties** . NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v** of this cell represents the membrane potential in that isopotential segment. + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for Cell are: +* biophysical_properties_attr (class: NmlId, Optional) +* morphology (class: Morphology, Optional) + * Contents ('ids'/): 'morphology' + +* neuro_lex_id (class: NeuroLexId, Optional) + * Contents ('ids'/): NLXCELL:091206 + +* metaid (class: MetaId, Optional) +* biophysical_properties (class: BiophysicalProperties, Optional) + * Contents ('ids'/): 'biophys' + +* id (class: NmlId, Required) + * Contents ('ids'/): olm + +* notes (class: xs:string, Optional) +* properties (class: Property, Optional) +* annotation (class: Annotation, Optional) +* morphology_attr (class: NmlId, Optional) + +``` + +We see the cell already contains `biophysical_properties` or `morphology`. +Because these are components of the cell that are expected to be used, these were added automatically for us when the new component was created. + +Let us take a look at the morphology of the cell: +```pycon +>>> cell.morphology.info(show_contents=True) +Morphology -- The collection of **segment** s which specify the 3D structure of the cell, along with a number of **segmentGroup** s + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for Morphology are: +* segments (class: Segment, Required) +* metaid (class: MetaId, Optional) +* segment_groups (class: SegmentGroup, Optional) + * Contents ('ids'/): ['all', 'soma_group', 'axon_group', 'dendrite_group'] + +* id (class: NmlId, Required) + * Contents ('ids'/): morphology + +* notes (class: xs:string, Optional) +* properties (class: Property, Optional) +* annotation (class: Annotation, Optional) +``` + +We see that there are no segments in the cell because we have not added any. +However, there are already a number of "default" segment groups that were automatically added for us: `all`, `soma_group`, `axon_group`, `dendrite_group`. +These groups allow us to keep track of all the segments, and of the segments forming the soma, the axon, and the dendrites of the cell respectively. +Take a look at the {ref}`conventions page ` for more information on these. + +We now have an empty cell. +Since we are building a multi-compartmental cell, we now proceed to define the detailed morphology of the cell. +We do this by adding {ref}`segments ` and grouping them in to {ref}`segment groups `. +We can add segments using the `add_segment` utility function, as we do for the segments forming the soma. +Here, our soma has two segments. +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 123-142 +---- +``` +The utility function takes the dimensions of the segment---it's {ref}`proximal ` and {ref}`distal ` co-ordinates and the diameter to create a segment of the provided name. +Additionally, since segments need to be contiguous, it makes the first segment the *parent* of the second, to build a chain. +Finally, it places the segment into the specified segment group and the default groups that we also have and adds the segment to the cell's morphology. + +Note that by default, the `add_segment` function does not know if the segments are contiguous, i.e., that they form an unbranched branch of the cell. +We could have added segments here that do not line up in a chain, when building different parts of a cell for example. +In this case, we know that the two soma segments must be contiguous, and that they are on the same unbranched branch (i.e. a continuous section without any branching points on it), so we create an unbranched segment group first using the `add_unbranched_segment_group`. + +If we were only creating cell morphologies, this would not not matter much. +Even if the two segments were not included in a group of unbranched segments, they would still be connected. +However, for simulation, simulators such as NEURON need to know which parts of the cell form unbranched sections so that they can apply the [cable equation](https://en.wikipedia.org/wiki/Cable_theory#Deriving_the_cable_equation) and break them into smaller segments to simulate the electric current through them. +(See {cite}`Crook2007` for more information on how different simulators simulate cells with detailed morphologies.) + +Next, we can call the same functions multiple times to add soma, dendritic, and axonal segments to our cell but this can get quite lengthy. +To easily add unbranched contiguous lists of segments to the cell, we can directly use the `add_unbranched_segments` utility function. +Here we use it to create an axonal segment group, and two dendritic groups each with two segments. +The first point we provide is the proximal (starting) of the dendrite. +The next two points are the distal (ends) of each segment forming the section. +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 144-183 +---- +``` +We repeat this process to create more dendritic and axonal sections of contiguous segments. + +Finally, we add an extra colour property to the three primary segment groups that can be used when generating morphology graphs: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 185-193 +---- +``` + +We have now completed adding the morphological information to our cell. +Next, we proceed to our {ref}`biophysical properties `, e.g.: +- the {ref}`membrane properties ` + - {ref}`spike threshold ` + - {ref}`initial membrane potential ` + - {ref}`channel densities ` + - {ref}`specifc capacitances ` +- the {ref}`intracellular properties ` + - {ref}`resistivity ` + +We use more helpful utility functions to set these values +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 195-198 +---- +``` +For setting channel densities, we have the `add_channel_density` function: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 200-289 +---- +``` +Note that we are not writing our channel files from scratch here. +We are re-using already written NeuroML channel definitions by simply including their NeuroML definition files. + +This completes the definition of our cell. +We now run the level one validation, write it to a file while also running a complete (level one and level two) validation using pyNeuroML. +We also generate the morphology plot shown on the top of this page. +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 291-294 +---- +``` +The resulting NeuroML file is: +```{literalinclude} ./NML2_examples/olm.cell.nml +---- +language: xml +``` +We can now already inspect our cell using the NeuroML tools. +We have already generated the morphology plot in our script, but we can also do it using `pynml`: +```{code-block} console +pynml -png olm.cell.png +... +pyNeuroML >>> Writing to: /home/asinha/Documents/02_Code/00_mine/2020-OSB/NeuroML-Documentation/source/Userdocs/NML2_examples/olm.cell.png +``` +This gives us a figure of the morphology of our cell, similar to the one we've already generated: +```{figure} ../Userdocs/NML2_examples/olm.cell.png +:alt: Figure showing the morphology of the OLM cell generated from the NeuroML definition. +:align: center + +Figure showing the morphology of the OLM cell generated from the NeuroML definition. +``` +### Declaring the network + +We now use our cell in a network. +Similar to our previous example, we are going to only create a network with one cell, and an {ref}`explicit input ` to the cell: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 87-109 +---- +``` +We start in the same way, by creating a new NeuroML document and including our cell file into it. +We then create a {ref}`population ` comprising of a single cell. +We create a {ref}`pulse generator ` as an {ref}`explicit input `, which targets our population. +Note that as the schema documentation for `ExplicitInput` notes, any current source (any component that *extends* {ref}`basePointCurrent `) can be used as an `ExplicitInput`. + +We add all of these to the {ref}`network ` and save (and validate) our network file. +The NeuroML file generated is below: +```{literalinclude} ./NML2_examples/olm_example_net.nml +---- +language: xml +``` +### The generated NeuroML model + +Before we look at simulating the model, we can inspect our model to check for correctness. +All our NeuroML files were validated when they were created already, so we do not need to run this step again. +However, if required, this can be easily done: +```{code-block} console +pynml -validate olm*nml +``` +Next, we can visualise our model using the information noted in the {ref}`visualising NeuroML models ` page (including the `-v` verbose option for more information on the cell): +```{code-block} console +pynml-summary olm_example_net.nml -v +******************************************************* +* NeuroMLDocument: network +* +* ComponentType: ['Bezaire_HCNolm_tau', 'Bezaire_Kdrfast_betaq', 'Bezaire_KvAolm_taub', 'Bezaire_Nav_alphah'] +* IonChannel: ['HCNolm', 'Kdrfast', 'KvAolm', 'Nav', 'leak_chan'] +* PulseGenerator: ['pg_olm'] +* +* Cell: olm +* +* Parent segment: None (root segment) +* (0.0, 0.0, 0.0), diam 10.0um -> (0.0, 10.0, 0.0), diam 10.0um; seg length: 10.0 um +* Surface area: 314.1592653589793 um2, volume: 785.3981633974482 um3 +* +* Parent segment: 0 +* None -> (0.0, 20.0, 0.0), diam 10.0um; seg length: 10.0 um +* Surface area: 314.1592653589793 um2, volume: 785.3981633974482 um3 +* +* Parent segment: 0 +* (0.0, 0.0, 0.0), diam 1.5um -> (0.0, -75.0, 0.0), diam 1.5um; seg length: 75.0 um +* Surface area: 353.4291735288517 um2, volume: 132.53594007331938 um3 +* +* Parent segment: 2 +* None -> (0.0, -150.0, 0.0), diam 1.5um; seg length: 75.0 um +* Surface area: 353.4291735288517 um2, volume: 132.53594007331938 um3 +* +* Parent segment: 1 +* (0.0, 20.0, 0.0), diam 3.0um -> (100.0, 120.0, 0.0), diam 3.0um; seg length: 141.4213562373095 um +* Surface area: 1332.8648814475098 um2, volume: 999.6486610856323 um3 +* +* Parent segment: 4 +* None -> (177.0, 197.0, 0.0), diam 3.0um; seg length: 108.89444430272832 um +* Surface area: 1026.3059587145826 um2, volume: 769.7294690359369 um3 +* +* Parent segment: 1 +* (0.0, 20.0, 0.0), diam 3.0um -> (-100.0, 120.0, 0.0), diam 3.0um; seg length: 141.4213562373095 um +* Surface area: 1332.8648814475098 um2, volume: 999.6486610856323 um3 +* +* Parent segment: 6 +* None -> (-177.0, 197.0, 0.0), diam 3.0um; seg length: 108.89444430272832 um +* Surface area: 1026.3059587145826 um2, volume: 769.7294690359369 um3 +* Total length of 8 segments: 670.6316010800756 um; total area: 6053.518558099847 um2 +* +* SegmentGroup: all, 8 member(s), 0 included group(s); contains 8 segments in total +* SegmentGroup: soma_group, 2 member(s), 1 included group(s); contains 2 segments in total +* SegmentGroup: axon_group, 2 member(s), 1 included group(s); contains 2 segments in total +* SegmentGroup: dendrite_group, 4 member(s), 2 included group(s); contains 4 segments in total +* SegmentGroup: soma_0, 2 member(s), 0 included group(s); contains 2 segments in total +* SegmentGroup: axon_0, 2 member(s), 0 included group(s); contains 2 segments in total +* SegmentGroup: dend_0, 2 member(s), 0 included group(s); contains 2 segments in total +* SegmentGroup: dend_1, 2 member(s), 0 included group(s); contains 2 segments in total +* +* Channel density: leak_all on all; conductance of 0.01 mS_per_cm2 through ion chan leak_chan with ion non_specific, erev: -67mV +* Channel is on , total conductance: 0.1 S_per_m2 x 3.1415926535897934e-10 m2 = 3.1415926535897936e-11 S (31.41592653589794 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 3.1415926535897934e-10 m2 = 3.1415926535897936e-11 S (31.41592653589794 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 3.534291735288517e-10 m2 = 3.534291735288518e-11 S (35.34291735288518 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 3.534291735288517e-10 m2 = 3.534291735288518e-11 S (35.34291735288518 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 1.3328648814475097e-09 m2 = 1.3328648814475097e-10 S (133.28648814475096 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0263059587145826e-10 S (102.63059587145825 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 1.3328648814475097e-09 m2 = 1.3328648814475097e-10 S (133.28648814475096 pS) +* Channel is on , total conductance: 0.1 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0263059587145826e-10 S (102.63059587145825 pS) +* Channel density: HCNolm_soma on soma_group; conductance of 0.5 mS_per_cm2 through ion chan HCNolm with ion h, erev: -32.9mV +* Channel is on , total conductance: 5.0 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5707963267948968e-09 S (1570.796326794897 pS) +* Channel is on , total conductance: 5.0 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5707963267948968e-09 S (1570.796326794897 pS) +* Channel density: Kdrfast_soma on soma_group; conductance of 73.37 mS_per_cm2 through ion chan Kdrfast with ion k, erev: -77mV +* Channel is on , total conductance: 733.7 S_per_m2 x 3.1415926535897934e-10 m2 = 2.3049865299388314e-07 S (230498.65299388315 pS) +* Channel is on , total conductance: 733.7 S_per_m2 x 3.1415926535897934e-10 m2 = 2.3049865299388314e-07 S (230498.65299388315 pS) +* Channel density: Kdrfast_dendrite on dendrite_group; conductance of 105.8 mS_per_cm2 through ion chan Kdrfast with ion k, erev: -77mV +* Channel is on , total conductance: 1058.0 S_per_m2 x 1.3328648814475097e-09 m2 = 1.4101710445714652e-06 S (1410171.0445714653 pS) +* Channel is on , total conductance: 1058.0 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0858317043200284e-06 S (1085831.7043200284 pS) +* Channel is on , total conductance: 1058.0 S_per_m2 x 1.3328648814475097e-09 m2 = 1.4101710445714652e-06 S (1410171.0445714653 pS) +* Channel is on , total conductance: 1058.0 S_per_m2 x 1.0263059587145826e-09 m2 = 1.0858317043200284e-06 S (1085831.7043200284 pS) +* Channel density: Kdrfast_axon on axon_group; conductance of 117.392 mS_per_cm2 through ion chan Kdrfast with ion k, erev: -77mV +* Channel is on , total conductance: 1173.92 S_per_m2 x 3.534291735288517e-10 m2 = 4.1489757538898964e-07 S (414897.57538898964 pS) +* Channel is on , total conductance: 1173.92 S_per_m2 x 3.534291735288517e-10 m2 = 4.1489757538898964e-07 S (414897.57538898964 pS) +* Channel density: KvAolm_soma on soma_group; conductance of 4.95 mS_per_cm2 through ion chan KvAolm with ion k, erev: -77mV +* Channel is on , total conductance: 49.5 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5550883635269477e-08 S (15550.883635269476 pS) +* Channel is on , total conductance: 49.5 S_per_m2 x 3.1415926535897934e-10 m2 = 1.5550883635269477e-08 S (15550.883635269476 pS) +* Channel density: KvAolm_dendrite on dendrite_group; conductance of 2.8 mS_per_cm2 through ion chan KvAolm with ion k, erev: -77mV +* Channel is on , total conductance: 28.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.7320216680530273e-08 S (37320.21668053028 pS) +* Channel is on , total conductance: 28.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.8736566844008313e-08 S (28736.566844008314 pS) +* Channel is on , total conductance: 28.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.7320216680530273e-08 S (37320.21668053028 pS) +* Channel is on , total conductance: 28.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.8736566844008313e-08 S (28736.566844008314 pS) +* Channel density: Nav_soma on soma_group; conductance of 10.7 mS_per_cm2 through ion chan Nav with ion na, erev: 50mV +* Channel is on , total conductance: 107.0 S_per_m2 x 3.1415926535897934e-10 m2 = 3.361504139341079e-08 S (33615.04139341079 pS) +* Channel is on , total conductance: 107.0 S_per_m2 x 3.1415926535897934e-10 m2 = 3.361504139341079e-08 S (33615.04139341079 pS) +* Channel density: Nav_dendrite on dendrite_group; conductance of 23.4 mS_per_cm2 through ion chan Nav with ion na, erev: 50mV +* Channel is on , total conductance: 234.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.118903822587173e-07 S (311890.3822587173 pS) +* Channel is on , total conductance: 234.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.401555943392123e-07 S (240155.59433921232 pS) +* Channel is on , total conductance: 234.0 S_per_m2 x 1.3328648814475097e-09 m2 = 3.118903822587173e-07 S (311890.3822587173 pS) +* Channel is on , total conductance: 234.0 S_per_m2 x 1.0263059587145826e-09 m2 = 2.401555943392123e-07 S (240155.59433921232 pS) +* Channel density: Nav_axon on axon_group; conductance of 17.12 mS_per_cm2 through ion chan Nav with ion na, erev: 50mV +* Channel is on , total conductance: 171.20000000000002 S_per_m2 x 3.534291735288517e-10 m2 = 6.050707450813942e-08 S (60507.07450813943 pS) +* Channel is on , total conductance: 171.20000000000002 S_per_m2 x 3.534291735288517e-10 m2 = 6.050707450813942e-08 S (60507.07450813943 pS) +* +* Specific capacitance on all: 1.3 uF_per_cm2 +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 3.1415926535897934e-10 m2 = 4.084070449666732e-12 F (4.084070449666732 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 3.1415926535897934e-10 m2 = 4.084070449666732e-12 F (4.084070449666732 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 3.534291735288517e-10 m2 = 4.594579255875073e-12 F (4.594579255875073 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 3.534291735288517e-10 m2 = 4.594579255875073e-12 F (4.594579255875073 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 1.3328648814475097e-09 m2 = 1.732724345881763e-11 F (17.32724345881763 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 1.0263059587145826e-09 m2 = 1.3341977463289574e-11 F (13.341977463289574 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 1.3328648814475097e-09 m2 = 1.732724345881763e-11 F (17.32724345881763 pF) +* Capacitance of , total capacitance: 0.013000000000000001 F_per_m2 x 1.0263059587145826e-09 m2 = 1.3341977463289574e-11 F (13.341977463289574 pF) +* +* Network: single_olm_cell_network +* +* 1 cells in 1 populations +* Population: pop0 with 1 components of type olm +* Locations: [(0, 0, 0), ...] +* +* 0 connections in 0 projections +* +* 0 inputs in 0 input lists +* +* 1 explicit inputs (outside of input lists) +* Explicit Input of type pg_olm to pop0(cell 0), destination: unspecified +* +******************************************************* + +``` +We can check the connectivity graph of the model: +```{code-block} console +pynml -graph 10 olm_example_net.nml +``` +which will give us this figure: +```{figure} ./NML2_examples/single_olm_cell_network.gv.png +:alt: Level 10 network graph generated by pynml +:align: center +:scale: 60 % + +Level 10 network graph generated by pynml +``` +## Simulating the model + +Please note that this example uses the {ref}`NEURON ` simulator to simulate the model. +Please ensure that the `NEURON_HOME` environment variable is correctly set as noted {ref}`here `. + +Now that we have declared and inspected our network model and all its components, we can proceed to simulate it. +We do this in the `main` function: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 20-68 +---- +``` +Here we first create a `LEMSSimulation` instance and include our network NeuroML file in it. +We must inform LEMS what the target of the simulation is. +In our case, it's the id of our network, `single_olm_cell_network`: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 28-32 +---- +``` +We also want to record some information, so we create an output file first with an `id` of `output0`: +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 36 +---- +``` +Now, we can record any quantity that is exposed by NeuroML (any `exposure`). +Here, for example, we add columns for the membrane potentials `v` of the different segments of the {ref}`cell `. +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 37-60 +---- +``` +The path required to point to the `quantity` (exposure) to be recorded needs to be correctly provided. +Here, where we use a {ref}`population list ` that includes an {ref}`instance ` of the cell, it is: `population_id/instance_id/cell component type/segment id/exposure`. (See tickets [15](https://github.com/NeuroML/Documentation/issues/15) and [16](https://github.com/NeuroML/Documentation/issues/16)) + + +We then save the LEMS simulation file, and run our simulation with the {ref}`NEURON ` simulator (since the default {ref}`jNeuroML ` simulator can only simulate single compartment cells). + +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 62-66 +---- +``` +## Plotting the recorded variables + +To plot the variables that we recorded, we write a simple function that reads the data and uses the `generate_plot` utility function which generates the membrane potential graphs for different segments. +```{literalinclude} ./NML2_examples/olm-example.py +---- +language: python +lines: 71-84 +---- +``` +This concludes this example. +Here we have seen how to create, simulate, record, and visualise a multi-compartment neuron. +In the next section, you will find an interactive notebook where you can play with this example. diff --git a/_sources/Userdocs/NML2_examples/HH_single_compartment.ipynb b/_sources/Userdocs/NML2_examples/HH_single_compartment.ipynb new file mode 100644 index 00000000..8207400f --- /dev/null +++ b/_sources/Userdocs/NML2_examples/HH_single_compartment.ipynb @@ -0,0 +1,471 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Interactive single compartment HH example\n", + "\n", + "To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. ", + "For more information, please see {ref}`how to use this documentation `. ", + "Please uncomment the line below if you use the Google Colab. (It does not include these packages by default)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#%pip install pyneuroml neuromllite NEURON" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "from neuroml import NeuroMLDocument\n", + "from neuroml import Cell\n", + "from neuroml import IonChannelHH\n", + "from neuroml import GateHHRates\n", + "from neuroml import BiophysicalProperties\n", + "from neuroml import MembraneProperties\n", + "from neuroml import ChannelDensity\n", + "from neuroml import HHRate\n", + "from neuroml import SpikeThresh\n", + "from neuroml import SpecificCapacitance\n", + "from neuroml import InitMembPotential\n", + "from neuroml import IntracellularProperties\n", + "from neuroml import IncludeType\n", + "from neuroml import Resistivity\n", + "from neuroml import Morphology, Segment, Point3DWithDiam\n", + "from neuroml import Network, Population\n", + "from neuroml import PulseGenerator, ExplicitInput\n", + "import numpy as np\n", + "from pyneuroml import pynml\n", + "from pyneuroml.lems import LEMSSimulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Declare the model\n", + "### Create ion channels" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def create_na_channel():\n", + " \"\"\"Create the Na channel.\n", + "\n", + " This will create the Na channel and save it to a file.\n", + " It will also validate this file.\n", + "\n", + " returns: name of the created file\n", + " \"\"\"\n", + " na_channel = IonChannelHH(id=\"na_channel\", notes=\"Sodium channel for HH cell\", conductance=\"10pS\", species=\"na\")\n", + " gate_m = GateHHRates(id=\"m\", instances=\"3\", notes=\"m gate for na channel\")\n", + "\n", + " m_forward_rate = HHRate(type=\"HHExpLinearRate\", rate=\"1per_ms\", midpoint=\"-40mV\", scale=\"10mV\")\n", + " m_reverse_rate = HHRate(type=\"HHExpRate\", rate=\"4per_ms\", midpoint=\"-65mV\", scale=\"-18mV\")\n", + " gate_m.forward_rate = m_forward_rate\n", + " gate_m.reverse_rate = m_reverse_rate\n", + " na_channel.gate_hh_rates.append(gate_m)\n", + "\n", + " gate_h = GateHHRates(id=\"h\", instances=\"1\", notes=\"h gate for na channel\")\n", + " h_forward_rate = HHRate(type=\"HHExpRate\", rate=\"0.07per_ms\", midpoint=\"-65mV\", scale=\"-20mV\")\n", + " h_reverse_rate = HHRate(type=\"HHSigmoidRate\", rate=\"1per_ms\", midpoint=\"-35mV\", scale=\"10mV\")\n", + " gate_h.forward_rate = h_forward_rate\n", + " gate_h.reverse_rate = h_reverse_rate\n", + " na_channel.gate_hh_rates.append(gate_h)\n", + "\n", + " na_channel_doc = NeuroMLDocument(id=\"na_channel\", notes=\"Na channel for HH neuron\")\n", + " na_channel_fn = \"HH_example_na_channel.nml\"\n", + " na_channel_doc.ion_channel_hhs.append(na_channel)\n", + "\n", + " pynml.write_neuroml2_file(nml2_doc=na_channel_doc, nml2_file_name=na_channel_fn, validate=True)\n", + "\n", + " return na_channel_fn" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def create_k_channel():\n", + " \"\"\"Create the K channel\n", + "\n", + " This will create the K channel and save it to a file.\n", + " It will also validate this file.\n", + "\n", + " :returns: name of the K channel file\n", + " \"\"\"\n", + " k_channel = IonChannelHH(id=\"k_channel\", notes=\"Potassium channel for HH cell\", conductance=\"10pS\", species=\"k\")\n", + " gate_n = GateHHRates(id=\"n\", instances=\"4\", notes=\"n gate for k channel\")\n", + " n_forward_rate = HHRate(type=\"HHExpLinearRate\", rate=\"0.1per_ms\", midpoint=\"-55mV\", scale=\"10mV\")\n", + " n_reverse_rate = HHRate(type=\"HHExpRate\", rate=\"0.125per_ms\", midpoint=\"-65mV\", scale=\"-80mV\")\n", + " gate_n.forward_rate = n_forward_rate\n", + " gate_n.reverse_rate = n_reverse_rate\n", + " k_channel.gate_hh_rates.append(gate_n)\n", + "\n", + " k_channel_doc = NeuroMLDocument(id=\"k_channel\", notes=\"k channel for HH neuron\")\n", + " k_channel_fn = \"HH_example_k_channel.nml\"\n", + " k_channel_doc.ion_channel_hhs.append(k_channel)\n", + "\n", + " pynml.write_neuroml2_file(nml2_doc=k_channel_doc, nml2_file_name=k_channel_fn, validate=True)\n", + "\n", + " return k_channel_fn" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def create_leak_channel():\n", + " \"\"\"Create a leak channel\n", + "\n", + " This will create the leak channel and save it to a file.\n", + " It will also validate this file.\n", + "\n", + " :returns: name of leak channel nml file\n", + " \"\"\"\n", + " leak_channel = IonChannelHH(id=\"leak_channel\", conductance=\"10pS\", notes=\"Leak conductance\")\n", + " leak_channel_doc = NeuroMLDocument(id=\"leak_channel\", notes=\"leak channel for HH neuron\")\n", + " leak_channel_fn = \"HH_example_leak_channel.nml\"\n", + " leak_channel_doc.ion_channel_hhs.append(leak_channel)\n", + "\n", + " pynml.write_neuroml2_file(nml2_doc=leak_channel_doc, nml2_file_name=leak_channel_fn, validate=True)\n", + "\n", + " return leak_channel_fn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create cell" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def create_cell():\n", + " \"\"\"Create the cell.\n", + "\n", + " :returns: name of the cell nml file\n", + " \"\"\"\n", + " # Create the nml file and add the ion channels\n", + " hh_cell_doc = NeuroMLDocument(id=\"cell\", notes=\"HH cell\")\n", + " hh_cell_fn = \"HH_example_cell.nml\"\n", + " hh_cell_doc.includes.append(IncludeType(href=create_na_channel()))\n", + " hh_cell_doc.includes.append(IncludeType(href=create_k_channel()))\n", + " hh_cell_doc.includes.append(IncludeType(href=create_leak_channel()))\n", + "\n", + " # Define a cell\n", + " hh_cell = Cell(id=\"hh_cell\", notes=\"A single compartment HH cell\")\n", + "\n", + " # Define its biophysical properties\n", + " bio_prop = BiophysicalProperties(id=\"hh_b_prop\")\n", + " # notes=\"Biophysical properties for HH cell\")\n", + "\n", + " # Membrane properties are a type of biophysical properties\n", + " mem_prop = MembraneProperties()\n", + " # Add membrane properties to the biophysical properties\n", + " bio_prop.membrane_properties = mem_prop\n", + "\n", + " # Append to cell\n", + " hh_cell.biophysical_properties = bio_prop\n", + "\n", + " # Channel density for Na channel\n", + " na_channel_density = ChannelDensity(id=\"na_channels\", cond_density=\"120.0 mS_per_cm2\", erev=\"50.0 mV\", ion=\"na\", ion_channel=\"na_channel\")\n", + " mem_prop.channel_densities.append(na_channel_density)\n", + "\n", + " # Channel density for k channel\n", + " k_channel_density = ChannelDensity(id=\"k_channels\", cond_density=\"360 S_per_m2\", erev=\"-77mV\", ion=\"k\", ion_channel=\"k_channel\")\n", + " mem_prop.channel_densities.append(k_channel_density)\n", + "\n", + " # Leak channel\n", + " leak_channel_density = ChannelDensity(id=\"leak_channels\", cond_density=\"3.0 S_per_m2\", erev=\"-54.3mV\", ion=\"non_specific\", ion_channel=\"leak_channel\")\n", + " mem_prop.channel_densities.append(leak_channel_density)\n", + "\n", + " # Other membrane properties\n", + " mem_prop.spike_threshes.append(SpikeThresh(value=\"-20mV\"))\n", + " mem_prop.specific_capacitances.append(SpecificCapacitance(value=\"1.0 uF_per_cm2\"))\n", + " mem_prop.init_memb_potentials.append(InitMembPotential(value=\"-65mV\"))\n", + "\n", + " intra_prop = IntracellularProperties()\n", + " intra_prop.resistivities.append(Resistivity(value=\"0.03 kohm_cm\"))\n", + "\n", + " # Add to biological properties\n", + " bio_prop.intracellular_properties = intra_prop\n", + "\n", + " # Morphology\n", + " morph = Morphology(id=\"hh_cell_morph\")\n", + " # notes=\"Simple morphology for the HH cell\")\n", + " seg = Segment(id=\"0\", name=\"soma\", notes=\"Soma segment\")\n", + " # We want a diameter such that area is 1000 micro meter^2\n", + " # surface area of a sphere is 4pi r^2 = 4pi diam^2\n", + " diam = math.sqrt(1000 / math.pi)\n", + " proximal = distal = Point3DWithDiam(x=\"0\", y=\"0\", z=\"0\", diameter=str(diam))\n", + " seg.proximal = proximal\n", + " seg.distal = distal\n", + " morph.segments.append(seg)\n", + " hh_cell.morphology = morph\n", + "\n", + " hh_cell_doc.cells.append(hh_cell)\n", + " pynml.write_neuroml2_file(nml2_doc=hh_cell_doc, nml2_file_name=hh_cell_fn, validate=True)\n", + " return hh_cell_fn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a network" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def create_network():\n", + " \"\"\"Create the network\n", + "\n", + " :returns: name of network nml file\n", + " \"\"\"\n", + " net_doc = NeuroMLDocument(id=\"network\",\n", + " notes=\"HH cell network\")\n", + " net_doc_fn = \"HH_example_net.nml\"\n", + " net_doc.includes.append(IncludeType(href=create_cell()))\n", + " # Create a population: convenient to create many cells of the same type\n", + " pop = Population(id=\"pop0\", notes=\"A population for our cell\", component=\"hh_cell\", size=1)\n", + " # Input\n", + " pulsegen = PulseGenerator(id=\"pg\", notes=\"Simple pulse generator\", delay=\"100ms\", duration=\"100ms\", amplitude=\"0.08nA\")\n", + "\n", + " exp_input = ExplicitInput(target=\"pop0[0]\", input=\"pg\")\n", + "\n", + " net = Network(id=\"single_hh_cell_network\", note=\"A network with a single population\")\n", + " net_doc.pulse_generators.append(pulsegen)\n", + " net.explicit_inputs.append(exp_input)\n", + " net.populations.append(pop)\n", + " net_doc.networks.append(net)\n", + "\n", + " pynml.write_neuroml2_file(nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True)\n", + " return net_doc_fn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot the data we record" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_data(sim_id):\n", + " \"\"\"Plot the sim data.\n", + "\n", + " Load the data from the file and plot the graph for the membrane potential\n", + " using the pynml generate_plot utility function.\n", + "\n", + " :sim_id: ID of simulaton\n", + "\n", + " \"\"\"\n", + " data_array = np.loadtxt(sim_id + \".dat\")\n", + " pynml.generate_plot([data_array[:, 0]], [data_array[:, 1]], \"Membrane potential\", show_plot_already=False, save_figure_to=sim_id + \"-v.png\", xaxis=\"time (s)\", yaxis=\"membrane potential (V)\")\n", + " pynml.generate_plot([data_array[:, 0]], [data_array[:, 2]], \"channel current\", show_plot_already=False, save_figure_to=sim_id + \"-i.png\", xaxis=\"time (s)\", yaxis=\"channel current (A)\")\n", + " pynml.generate_plot([data_array[:, 0], data_array[:, 0]], [data_array[:, 3], data_array[:, 4]], \"current density\", labels=[\"Na\", \"K\"], show_plot_already=False, save_figure_to=sim_id + \"-iden.png\", xaxis=\"time (s)\", yaxis=\"current density (A_per_m2)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create and run the simulation\n", + "\n", + "Create the simulation, run it, record data, and plot the recorded information." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def main():\n", + " \"\"\"Main function\n", + "\n", + " Include the NeuroML model into a LEMS simulation file, run it, plot some\n", + " data.\n", + " \"\"\"\n", + " # Simulation bits\n", + " sim_id = \"HH_single_compartment_example_sim\"\n", + " simulation = LEMSSimulation(sim_id=sim_id, duration=300, dt=0.01, simulation_seed=123)\n", + " # Include the NeuroML model file\n", + " simulation.include_neuroml2_file(create_network())\n", + " # Assign target for the simulation\n", + " simulation.assign_simulation_target(\"single_hh_cell_network\")\n", + "\n", + " # Recording information from the simulation\n", + " simulation.create_output_file(id=\"output0\", file_name=sim_id + \".dat\")\n", + " simulation.add_column_to_output_file(\"output0\", column_id=\"pop0[0]/v\", quantity=\"pop0[0]/v\")\n", + " simulation.add_column_to_output_file(\"output0\", column_id=\"pop0[0]/iChannels\", quantity=\"pop0[0]/iChannels\")\n", + " simulation.add_column_to_output_file(\"output0\", column_id=\"pop0[0]/na/iDensity\", quantity=\"pop0[0]/hh_b_prop/membraneProperties/na_channels/iDensity/\")\n", + " simulation.add_column_to_output_file(\"output0\", column_id=\"pop0[0]/k/iDensity\", quantity=\"pop0[0]/hh_b_prop/membraneProperties/k_channels/iDensity/\")\n", + "\n", + " # Save LEMS simulation to file\n", + " sim_file = simulation.save_to_file()\n", + "\n", + " # Run the simulation using the default jNeuroML simulator\n", + " pynml.run_lems_with_jneuroml(sim_file, max_memory=\"2G\", nogui=True, plot=False)\n", + " # Plot the data\n", + " plot_data(sim_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pyNeuroML >>> Written LEMS Simulation HH_single_compartment_example_sim to file: LEMS_HH_single_compartment_example_sim.xml\n", + "pyNeuroML >>> Generating plot: Membrane potential\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1688: MatplotlibDeprecationWarning: \n", + "The set_window_title function was deprecated in Matplotlib 3.4 and will be removed two minor releases later. Use manager.set_window_title or GUI-specific methods instead.\n", + " fig.canvas.set_window_title(title)\n", + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n", + " plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)\n", + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1688: MatplotlibDeprecationWarning: \n", + "The set_window_title function was deprecated in Matplotlib 3.4 and will be removed two minor releases later. Use manager.set_window_title or GUI-specific methods instead.\n", + " fig.canvas.set_window_title(title)\n", + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n", + " plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pyNeuroML >>> Saved image to HH_single_compartment_example_sim-v.png of plot: Membrane potential\n", + "pyNeuroML >>> Generating plot: channel current\n", + "pyNeuroML >>> Saved image to HH_single_compartment_example_sim-i.png of plot: channel current\n", + "pyNeuroML >>> Generating plot: current density\n", + "pyNeuroML >>> Saved image to HH_single_compartment_example_sim-iden.png of plot: current density\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1688: MatplotlibDeprecationWarning: \n", + "The set_window_title function was deprecated in Matplotlib 3.4 and will be removed two minor releases later. Use manager.set_window_title or GUI-specific methods instead.\n", + " fig.canvas.set_window_title(title)\n", + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n", + " plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)\n", + "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py:1727: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n", + " plt.plot(xvalues[i], yvalues[i], 'o', marker=marker, markersize=markersize, linestyle=linestyle, linewidth=linewidth, label=label)\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.9.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/Userdocs/NML2_examples/IzhikevichNetwork.ipynb b/_sources/Userdocs/NML2_examples/IzhikevichNetwork.ipynb new file mode 100644 index 00000000..7c0f36ad --- /dev/null +++ b/_sources/Userdocs/NML2_examples/IzhikevichNetwork.ipynb @@ -0,0 +1,915 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Interactive two population network example\n", + "\n", + "To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see {ref}`how to use this documentation `. Please uncomment the line below if you use the Google Colab. (It does not include these packages by default)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#%pip install pyneuroml neuromllite NEURON" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#!/usr/bin/env python3\n", + "\"\"\"\n", + "Create a simple network with two populations.\n", + "\"\"\"\n", + "\n", + "import random\n", + "import numpy as np\n", + "\n", + "from neuroml.utils import component_factory\n", + "from pyneuroml import pynml\n", + "from pyneuroml.lems import LEMSSimulation\n", + "import neuroml.writers as writers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Declaring the NeuroML model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a NeuroML document" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "nml_doc = component_factory(\"NeuroMLDocument\", id=\"IzNet\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Declare the Izhikevich cell and add it to the model document" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press\n", + "\n", + "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n", + "\n", + "Valid members for Izhikevich2007Cell are:\n", + "* a (class: Nml2Quantity_pertime, Required)\n", + "\t* Contents ('ids'/): 0.03per_ms\n", + "\n", + "* C (class: Nml2Quantity_capacitance, Required)\n", + "\t* Contents ('ids'/): 100pF\n", + "\n", + "* annotation (class: Annotation, Optional)\n", + "* b (class: Nml2Quantity_conductance, Required)\n", + "\t* Contents ('ids'/): -2nS\n", + "\n", + "* metaid (class: MetaId, Optional)\n", + "* c (class: Nml2Quantity_voltage, Required)\n", + "\t* Contents ('ids'/): -50.0mV\n", + "\n", + "* d (class: Nml2Quantity_current, Required)\n", + "\t* Contents ('ids'/): 100pA\n", + "\n", + "* neuro_lex_id (class: NeuroLexId, Optional)\n", + "* v0 (class: Nml2Quantity_voltage, Required)\n", + "\t* Contents ('ids'/): -60mV\n", + "\n", + "* properties (class: Property, Optional)\n", + "* k (class: Nml2Quantity_conductancePerVoltage, Required)\n", + "\t* Contents ('ids'/): 0.7nS_per_mV\n", + "\n", + "* notes (class: xs:string, Optional)\n", + "* vr (class: Nml2Quantity_voltage, Required)\n", + "\t* Contents ('ids'/): -60mV\n", + "\n", + "* vt (class: Nml2Quantity_voltage, Required)\n", + "\t* Contents ('ids'/): -40mV\n", + "\n", + "* vpeak (class: Nml2Quantity_voltage, Required)\n", + "\t* Contents ('ids'/): 35mV\n", + "\n", + "* id (class: NmlId, Required)\n", + "\t* Contents ('ids'/): iz2007RS0\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "\"Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press\\n\\nPlease see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for Izhikevich2007Cell are:\\n* a (class: Nml2Quantity_pertime, Required)\\n\\t* Contents ('ids'/): 0.03per_ms\\n\\n* C (class: Nml2Quantity_capacitance, Required)\\n\\t* Contents ('ids'/): 100pF\\n\\n* annotation (class: Annotation, Optional)\\n* b (class: Nml2Quantity_conductance, Required)\\n\\t* Contents ('ids'/): -2nS\\n\\n* metaid (class: MetaId, Optional)\\n* c (class: Nml2Quantity_voltage, Required)\\n\\t* Contents ('ids'/): -50.0mV\\n\\n* d (class: Nml2Quantity_current, Required)\\n\\t* Contents ('ids'/): 100pA\\n\\n* neuro_lex_id (class: NeuroLexId, Optional)\\n* v0 (class: Nml2Quantity_voltage, Required)\\n\\t* Contents ('ids'/): -60mV\\n\\n* properties (class: Property, Optional)\\n* k (class: Nml2Quantity_conductancePerVoltage, Required)\\n\\t* Contents ('ids'/): 0.7nS_per_mV\\n\\n* notes (class: xs:string, Optional)\\n* vr (class: Nml2Quantity_voltage, Required)\\n\\t* Contents ('ids'/): -60mV\\n\\n* vt (class: Nml2Quantity_voltage, Required)\\n\\t* Contents ('ids'/): -40mV\\n\\n* vpeak (class: Nml2Quantity_voltage, Required)\\n\\t* Contents ('ids'/): 35mV\\n\\n* id (class: NmlId, Required)\\n\\t* Contents ('ids'/): iz2007RS0\\n\\n\"" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "iz0 = nml_doc.add(\n", + " \"Izhikevich2007Cell\",\n", + " id=\"iz2007RS0\",\n", + " v0=\"-60mV\",\n", + " C=\"100pF\",\n", + " k=\"0.7nS_per_mV\",\n", + " vr=\"-60mV\",\n", + " vt=\"-40mV\",\n", + " vpeak=\"35mV\",\n", + " a=\"0.03per_ms\",\n", + " b=\"-2nS\",\n", + " c=\"-50.0mV\",\n", + " d=\"100pA\",\n", + ")\n", + "# Inspect the component, also show all members:\n", + "iz0.info(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Declare the Synapse and add it to the model document" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "syn0 = nml_doc.add(\n", + " \"ExpOneSynapse\", id=\"syn0\", gbase=\"65nS\", erev=\"0mV\", tau_decay=\"3ms\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n", + "\n", + "Valid members for NeuroMLDocument are:\n", + "* compound_inputs (class: CompoundInput, Optional)\n", + "* compound_input_dls (class: CompoundInputDL, Optional)\n", + "* includes (class: IncludeType, Optional)\n", + "* voltage_clamps (class: VoltageClamp, Optional)\n", + "* extracellular_properties (class: ExtracellularProperties, Optional)\n", + "* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n", + "* intracellular_properties (class: IntracellularProperties, Optional)\n", + "* spike_arrays (class: SpikeArray, Optional)\n", + "* morphology (class: Morphology, Optional)\n", + "* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n", + "* ion_channel (class: IonChannel, Optional)\n", + "* spike_generators (class: SpikeGenerator, Optional)\n", + "* ion_channel_hhs (class: IonChannelHH, Optional)\n", + "* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n", + "* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n", + "* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n", + "* ion_channel_kses (class: IonChannelKS, Optional)\n", + "* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n", + "* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n", + "* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n", + "* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n", + "* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n", + "* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n", + "* IF_curr_alpha (class: IF_curr_alpha, Optional)\n", + "* alpha_synapses (class: AlphaSynapse, Optional)\n", + "* IF_curr_exp (class: IF_curr_exp, Optional)\n", + "* exp_one_synapses (class: ExpOneSynapse, Optional)\n", + "\t* Contents ('ids'/): ['syn0']\n", + "\n", + "* IF_cond_alpha (class: IF_cond_alpha, Optional)\n", + "* exp_two_synapses (class: ExpTwoSynapse, Optional)\n", + "* IF_cond_exp (class: IF_cond_exp, Optional)\n", + "* exp_three_synapses (class: ExpThreeSynapse, Optional)\n", + "* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n", + "* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n", + "* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n", + "* double_synapses (class: DoubleSynapse, Optional)\n", + "* HH_cond_exp (class: HH_cond_exp, Optional)\n", + "* gap_junctions (class: GapJunction, Optional)\n", + "* exp_cond_synapses (class: ExpCondSynapse, Optional)\n", + "* silent_synapses (class: SilentSynapse, Optional)\n", + "* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n", + "* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n", + "* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n", + "* graded_synapses (class: GradedSynapse, Optional)\n", + "* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n", + "* annotation (class: Annotation, Optional)\n", + "* biophysical_properties (class: BiophysicalProperties, Optional)\n", + "* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n", + "* cells (class: Cell, Optional)\n", + "* networks (class: Network, Optional)\n", + "* cell2_ca_poolses (class: Cell2CaPools, Optional)\n", + "* ComponentType (class: ComponentType, Optional)\n", + "* base_cells (class: BaseCell, Optional)\n", + "* iaf_tau_cells (class: IafTauCell, Optional)\n", + "* properties (class: Property, Optional)\n", + "* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n", + "* notes (class: xs:string, Optional)\n", + "* iaf_cells (class: IafCell, Optional)\n", + "* metaid (class: MetaId, Optional)\n", + "* iaf_ref_cells (class: IafRefCell, Optional)\n", + "* izhikevich_cells (class: IzhikevichCell, Optional)\n", + "* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n", + "\t* Contents ('ids'/): ['iz2007RS0']\n", + "\n", + "* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n", + "* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n", + "* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n", + "* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n", + "* pulse_generators (class: PulseGenerator, Optional)\n", + "* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n", + "* sine_generators (class: SineGenerator, Optional)\n", + "* sine_generator_dls (class: SineGeneratorDL, Optional)\n", + "* ramp_generators (class: RampGenerator, Optional)\n", + "* ramp_generator_dls (class: RampGeneratorDL, Optional)\n", + "* id (class: NmlId, Required)\n", + "\t* Contents ('ids'/): IzNet\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "\"Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for NeuroMLDocument are:\\n* compound_inputs (class: CompoundInput, Optional)\\n* compound_input_dls (class: CompoundInputDL, Optional)\\n* includes (class: IncludeType, Optional)\\n* voltage_clamps (class: VoltageClamp, Optional)\\n* extracellular_properties (class: ExtracellularProperties, Optional)\\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\\n* intracellular_properties (class: IntracellularProperties, Optional)\\n* spike_arrays (class: SpikeArray, Optional)\\n* morphology (class: Morphology, Optional)\\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\\n* ion_channel (class: IonChannel, Optional)\\n* spike_generators (class: SpikeGenerator, Optional)\\n* ion_channel_hhs (class: IonChannelHH, Optional)\\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\\n* ion_channel_kses (class: IonChannelKS, Optional)\\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\\n* alpha_synapses (class: AlphaSynapse, Optional)\\n* IF_curr_exp (class: IF_curr_exp, Optional)\\n* exp_one_synapses (class: ExpOneSynapse, Optional)\\n\\t* Contents ('ids'/): ['syn0']\\n\\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\\n* IF_cond_exp (class: IF_cond_exp, Optional)\\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\\n* double_synapses (class: DoubleSynapse, Optional)\\n* HH_cond_exp (class: HH_cond_exp, Optional)\\n* gap_junctions (class: GapJunction, Optional)\\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\\n* silent_synapses (class: SilentSynapse, Optional)\\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\\n* graded_synapses (class: GradedSynapse, Optional)\\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\\n* annotation (class: Annotation, Optional)\\n* biophysical_properties (class: BiophysicalProperties, Optional)\\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\\n* cells (class: Cell, Optional)\\n* networks (class: Network, Optional)\\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\\n* ComponentType (class: ComponentType, Optional)\\n* base_cells (class: BaseCell, Optional)\\n* iaf_tau_cells (class: IafTauCell, Optional)\\n* properties (class: Property, Optional)\\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\\n* notes (class: xs:string, Optional)\\n* iaf_cells (class: IafCell, Optional)\\n* metaid (class: MetaId, Optional)\\n* iaf_ref_cells (class: IafRefCell, Optional)\\n* izhikevich_cells (class: IzhikevichCell, Optional)\\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\\n\\t* Contents ('ids'/): ['iz2007RS0']\\n\\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\\n* pulse_generators (class: PulseGenerator, Optional)\\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\\n* sine_generators (class: SineGenerator, Optional)\\n* sine_generator_dls (class: SineGeneratorDL, Optional)\\n* ramp_generators (class: RampGenerator, Optional)\\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\\n* id (class: NmlId, Required)\\n\\t* Contents ('ids'/): IzNet\\n\\n\"" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nml_doc.info(True)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*******************************************************\n", + "* NeuroMLDocument: IzNet\n", + "*\n", + "* ExpOneSynapse: ['syn0']\n", + "* Izhikevich2007Cell: ['iz2007RS0']\n", + "*\n", + "*******************************************************\n" + ] + } + ], + "source": [ + "print(nml_doc.summary())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Declare a Network and add it to the model document" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "net = nml_doc.add(\"Network\", id=\"IzNet\", validate=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create two populations" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# create the first population\n", + "size0 = 5\n", + "pop0 = component_factory(\"Population\", id=\"IzPop0\", component=iz0.id, size=size0, type=\"population\")\n", + "# Set optional color property. Note: used later when generating plots\n", + "pop0.add(\"Property\", tag=\"color\", value=\"0 0 .8\")\n", + "net.add(pop0)\n", + "\n", + "# create the second population\n", + "size1 = 5\n", + "pop1 = component_factory(\"Population\", id=\"IzPop1\", component=iz0.id, size=size1, type=\"population\")\n", + "pop1.add(\"Property\", tag=\"color\", value=\".8 0 0\")\n", + "net.add(pop1)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "net.validate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Declare projections" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# create a projection from one population to another\n", + "proj = net.add(\n", + " \"Projection\",\n", + " id=\"proj\",\n", + " presynaptic_population=pop0.id,\n", + " postsynaptic_population=pop1.id,\n", + " synapse=syn0.id,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add the projections between populations and the external inputs" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "random.seed(123)\n", + "prob_connection = 0.8\n", + "count = 0\n", + "for pre in range(0, size0):\n", + " # pulse generator as explicit stimulus\n", + " pg = nml_doc.add(\n", + " \"PulseGenerator\",\n", + " id=\"pg_%i\" % pre,\n", + " delay=\"0ms\",\n", + " duration=\"10000ms\",\n", + " amplitude=\"%f nA\" % (0.1 + 0.1 * random.random()),\n", + " )\n", + "\n", + " exp_input = net.add(\n", + " \"ExplicitInput\", target=\"%s[%i]\" % (pop0.id, pre), input=pg.id\n", + " )\n", + "\n", + " # synapses between populations\n", + " for post in range(0, size1):\n", + " if random.random() <= prob_connection:\n", + " syn = proj.add(\n", + " \"Connection\",\n", + " id=count,\n", + " pre_cell_id=\"../%s[%i]\" % (pop0.id, pre),\n", + " post_cell_id=\"../%s[%i]\" % (pop1.id, post),\n", + " )\n", + " count += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n", + "\n", + "Valid members for NeuroMLDocument are:\n", + "* compound_inputs (class: CompoundInput, Optional)\n", + "* compound_input_dls (class: CompoundInputDL, Optional)\n", + "* includes (class: IncludeType, Optional)\n", + "* voltage_clamps (class: VoltageClamp, Optional)\n", + "* extracellular_properties (class: ExtracellularProperties, Optional)\n", + "* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n", + "* intracellular_properties (class: IntracellularProperties, Optional)\n", + "* spike_arrays (class: SpikeArray, Optional)\n", + "* morphology (class: Morphology, Optional)\n", + "* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n", + "* ion_channel (class: IonChannel, Optional)\n", + "* spike_generators (class: SpikeGenerator, Optional)\n", + "* ion_channel_hhs (class: IonChannelHH, Optional)\n", + "* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n", + "* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n", + "* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n", + "* ion_channel_kses (class: IonChannelKS, Optional)\n", + "* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n", + "* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n", + "* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n", + "* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n", + "* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n", + "* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n", + "* IF_curr_alpha (class: IF_curr_alpha, Optional)\n", + "* alpha_synapses (class: AlphaSynapse, Optional)\n", + "* IF_curr_exp (class: IF_curr_exp, Optional)\n", + "* exp_one_synapses (class: ExpOneSynapse, Optional)\n", + "\t* Contents ('ids'/): ['syn0']\n", + "\n", + "* IF_cond_alpha (class: IF_cond_alpha, Optional)\n", + "* exp_two_synapses (class: ExpTwoSynapse, Optional)\n", + "* IF_cond_exp (class: IF_cond_exp, Optional)\n", + "* exp_three_synapses (class: ExpThreeSynapse, Optional)\n", + "* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n", + "* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n", + "* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n", + "* double_synapses (class: DoubleSynapse, Optional)\n", + "* HH_cond_exp (class: HH_cond_exp, Optional)\n", + "* gap_junctions (class: GapJunction, Optional)\n", + "* exp_cond_synapses (class: ExpCondSynapse, Optional)\n", + "* silent_synapses (class: SilentSynapse, Optional)\n", + "* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n", + "* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n", + "* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n", + "* graded_synapses (class: GradedSynapse, Optional)\n", + "* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n", + "* annotation (class: Annotation, Optional)\n", + "* biophysical_properties (class: BiophysicalProperties, Optional)\n", + "* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n", + "* cells (class: Cell, Optional)\n", + "* networks (class: Network, Optional)\n", + "\t* Contents ('ids'/): ['IzNet']\n", + "\n", + "* cell2_ca_poolses (class: Cell2CaPools, Optional)\n", + "* ComponentType (class: ComponentType, Optional)\n", + "* base_cells (class: BaseCell, Optional)\n", + "* iaf_tau_cells (class: IafTauCell, Optional)\n", + "* properties (class: Property, Optional)\n", + "* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n", + "* notes (class: xs:string, Optional)\n", + "* iaf_cells (class: IafCell, Optional)\n", + "* metaid (class: MetaId, Optional)\n", + "* iaf_ref_cells (class: IafRefCell, Optional)\n", + "* izhikevich_cells (class: IzhikevichCell, Optional)\n", + "* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n", + "\t* Contents ('ids'/): ['iz2007RS0']\n", + "\n", + "* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n", + "* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n", + "* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n", + "* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n", + "* pulse_generators (class: PulseGenerator, Optional)\n", + "\t* Contents ('ids'/): ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']\n", + "\n", + "* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n", + "* sine_generators (class: SineGenerator, Optional)\n", + "* sine_generator_dls (class: SineGeneratorDL, Optional)\n", + "* ramp_generators (class: RampGenerator, Optional)\n", + "* ramp_generator_dls (class: RampGeneratorDL, Optional)\n", + "* id (class: NmlId, Required)\n", + "\t* Contents ('ids'/): IzNet\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "\"Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for NeuroMLDocument are:\\n* compound_inputs (class: CompoundInput, Optional)\\n* compound_input_dls (class: CompoundInputDL, Optional)\\n* includes (class: IncludeType, Optional)\\n* voltage_clamps (class: VoltageClamp, Optional)\\n* extracellular_properties (class: ExtracellularProperties, Optional)\\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\\n* intracellular_properties (class: IntracellularProperties, Optional)\\n* spike_arrays (class: SpikeArray, Optional)\\n* morphology (class: Morphology, Optional)\\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\\n* ion_channel (class: IonChannel, Optional)\\n* spike_generators (class: SpikeGenerator, Optional)\\n* ion_channel_hhs (class: IonChannelHH, Optional)\\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\\n* ion_channel_kses (class: IonChannelKS, Optional)\\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\\n* alpha_synapses (class: AlphaSynapse, Optional)\\n* IF_curr_exp (class: IF_curr_exp, Optional)\\n* exp_one_synapses (class: ExpOneSynapse, Optional)\\n\\t* Contents ('ids'/): ['syn0']\\n\\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\\n* IF_cond_exp (class: IF_cond_exp, Optional)\\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\\n* double_synapses (class: DoubleSynapse, Optional)\\n* HH_cond_exp (class: HH_cond_exp, Optional)\\n* gap_junctions (class: GapJunction, Optional)\\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\\n* silent_synapses (class: SilentSynapse, Optional)\\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\\n* graded_synapses (class: GradedSynapse, Optional)\\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\\n* annotation (class: Annotation, Optional)\\n* biophysical_properties (class: BiophysicalProperties, Optional)\\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\\n* cells (class: Cell, Optional)\\n* networks (class: Network, Optional)\\n\\t* Contents ('ids'/): ['IzNet']\\n\\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\\n* ComponentType (class: ComponentType, Optional)\\n* base_cells (class: BaseCell, Optional)\\n* iaf_tau_cells (class: IafTauCell, Optional)\\n* properties (class: Property, Optional)\\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\\n* notes (class: xs:string, Optional)\\n* iaf_cells (class: IafCell, Optional)\\n* metaid (class: MetaId, Optional)\\n* iaf_ref_cells (class: IafRefCell, Optional)\\n* izhikevich_cells (class: IzhikevichCell, Optional)\\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\\n\\t* Contents ('ids'/): ['iz2007RS0']\\n\\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\\n* pulse_generators (class: PulseGenerator, Optional)\\n\\t* Contents ('ids'/): ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']\\n\\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\\n* sine_generators (class: SineGenerator, Optional)\\n* sine_generator_dls (class: SineGeneratorDL, Optional)\\n* ramp_generators (class: RampGenerator, Optional)\\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\\n* id (class: NmlId, Required)\\n\\t* Contents ('ids'/): IzNet\\n\\n\"" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nml_doc.info(True)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*******************************************************\n", + "* NeuroMLDocument: IzNet\n", + "*\n", + "* ExpOneSynapse: ['syn0']\n", + "* Izhikevich2007Cell: ['iz2007RS0']\n", + "* PulseGenerator: ['pg_0', 'pg_1', 'pg_2', 'pg_3', 'pg_4']\n", + "*\n", + "* Network: IzNet\n", + "*\n", + "* 10 cells in 2 populations \n", + "* Population: IzPop0 with 5 components of type iz2007RS0\n", + "* Properties: color=0 0 .8; \n", + "* Population: IzPop1 with 5 components of type iz2007RS0\n", + "* Properties: color=.8 0 0; \n", + "*\n", + "* 20 connections in 1 projections \n", + "* Projection: proj from IzPop0 to IzPop1, synapse: syn0\n", + "* 20 connections: [(Connection 0: 0 -> 0), ...]\n", + "*\n", + "* 0 inputs in 0 input lists \n", + "*\n", + "* 5 explicit inputs (outside of input lists)\n", + "* Explicit Input of type pg_0 to IzPop0(cell 0), destination: unspecified\n", + "* Explicit Input of type pg_1 to IzPop0(cell 1), destination: unspecified\n", + "* Explicit Input of type pg_2 to IzPop0(cell 2), destination: unspecified\n", + "* Explicit Input of type pg_3 to IzPop0(cell 3), destination: unspecified\n", + "* Explicit Input of type pg_4 to IzPop0(cell 4), destination: unspecified\n", + "*\n", + "*******************************************************\n" + ] + } + ], + "source": [ + "print(nml_doc.summary())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Write the NeuroML model to a NeuroML file and validate it" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -jar \"/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar\" -validate \"izhikevich2007_network.nml\" ) in directory: .\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Written network file to: izhikevich2007_network.nml\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Command completed. Output: \n", + " jNeuroML >> jNeuroML v0.12.0\n", + " jNeuroML >> Validating: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/izhikevich2007_network.nml\n", + " jNeuroML >> Valid against schema and all tests\n", + " jNeuroML >> No warnings\n", + " jNeuroML >> \n", + " jNeuroML >> Validated 1 files: All valid and no warnings\n", + " jNeuroML >> \n", + " jNeuroML >> \n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nml_file = 'izhikevich2007_network.nml'\n", + "writers.NeuroMLWriter.write(nml_doc, nml_file)\n", + "\n", + "print(\"Written network file to: \" + nml_file)\n", + "pynml.validate_neuroml2(nml_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simulating the model\n", + "### Create a simulation instance of the model" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/izhikevich2007_network.nml\n" + ] + } + ], + "source": [ + "simulation_id = \"example_izhikevich2007network_sim\"\n", + "simulation = LEMSSimulation(sim_id=simulation_id,\n", + " duration=1000, dt=0.1, simulation_seed=123)\n", + "simulation.assign_simulation_target(net.id)\n", + "simulation.include_neuroml2_file(nml_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the output file to store spikes" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "simulation.create_event_output_file(\n", + " \"pop0\", \"%s.0.spikes.dat\" % simulation_id, format='ID_TIME'\n", + ")\n", + "for pre in range(0, size0):\n", + " simulation.add_selection_to_event_output_file(\n", + " \"pop0\", pre, 'IzPop0[{}]'.format(pre), 'spike')\n", + "\n", + "simulation.create_event_output_file(\n", + " \"pop1\", \"%s.1.spikes.dat\" % simulation_id, format='ID_TIME'\n", + ")\n", + "for pre in range(0, size1):\n", + " simulation.add_selection_to_event_output_file(\n", + " \"pop1\", pre, 'IzPop1[{}]'.format(pre), 'spike')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Save the simulation to a file" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "lems_simulation_file = simulation.save_to_file()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the simulation using jNeuroML" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading LEMS file: LEMS_example_izhikevich2007network_sim.xml and running with jNeuroML_NEURON\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx2G -Djava.awt.headless=true -jar \"/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar\" \"LEMS_example_izhikevich2007network_sim.xml\" -neuron -run -compile -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed. Output: \n", + " jNeuroML >> jNeuroML v0.12.0\n", + " jNeuroML >> (INFO) Reading from: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.xml\n", + " jNeuroML >> (INFO) Creating NeuronWriter to output files to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples\n", + " jNeuroML >> (INFO) Adding simulation Component(id=example_izhikevich2007network_sim type=Simulation) of network/component: IzNet (Type: network)\n", + " jNeuroML >> (INFO) Adding population: IzPop0\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/iz2007RS0.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/iz2007RS0.mod exists and is identical\n", + " jNeuroML >> (INFO) Adding population: IzPop1\n", + " jNeuroML >> (INFO) -- Mod file for: iz2007RS0 has already been created\n", + " jNeuroML >> (INFO) Adding projections/connections...\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/syn0.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/syn0.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_0.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_0.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_1.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_1.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_2.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_2.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_3.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_3.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_4.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_4.mod exists and is identical\n", + " jNeuroML >> (INFO) Trying to compile mods in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples\n", + " jNeuroML >> (INFO) Going to compile the mod files in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples, forcing recompile: false\n", + " jNeuroML >> (INFO) Parent dir: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples\n", + " jNeuroML >> (INFO) Assuming *nix environment...\n", + " jNeuroML >> (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.la\n", + " jNeuroML >> (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so\n", + " jNeuroML >> (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so\n", + " jNeuroML >> (INFO) commandToExecute: /usr/bin/nrnivmodl\n", + " jNeuroML >> (INFO) Found previously compiled file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so\n", + " jNeuroML >> (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so\n", + " jNeuroML >> (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so\n", + " jNeuroML >> (INFO) Not being asked to recompile, and no mod files exist in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples which are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so\n", + " jNeuroML >> (INFO) Success in compiling mods: true\n", + " jNeuroML >> (INFO) Have successfully executed command: python /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim_nrn.py\n", + " jNeuroML >> (INFO) NRN Output >>> \n", + " jNeuroML >> (INFO) NRN Output >>> Starting simulation in NEURON of 1000ms generated from NeuroML2 model...\n", + " jNeuroML >> (INFO) NRN Output >>> \n", + " jNeuroML >> (INFO) NRN Output >>> Population IzPop0 contains 5 instance(s) of component: iz2007RS0 of type: izhikevich2007Cell\n", + " jNeuroML >> (INFO) NRN Output >>> Population IzPop1 contains 5 instance(s) of component: iz2007RS0 of type: izhikevich2007Cell\n", + " jNeuroML >> (INFO) NRN Output >>> Adding projection: proj, from IzPop0 to IzPop1 with synapse syn0, 20 connection(s)\n", + " jNeuroML >> (INFO) NRN Output >>> Setting up the network to simulate took 0.000990 seconds\n", + " jNeuroML >> (INFO) NRN Output >>> Running a simulation of 1000.0ms (dt = 0.1ms; seed=123)\n", + " jNeuroML >> (INFO) NRN Output >>> Finished NEURON simulation in 0.022036 seconds (0.000367 mins)...\n", + " jNeuroML >> (INFO) NRN Output >>> Saving results at t=999.9999999996382...\n", + " jNeuroML >> (INFO) NRN Output >>> Saved data to: time.dat\n", + " jNeuroML >> (INFO) NRN Output >>> Saved data to: example_izhikevich2007network_sim.1.spikes.dat\n", + " jNeuroML >> (INFO) NRN Output >>> Saved data to: example_izhikevich2007network_sim.0.spikes.dat\n", + " jNeuroML >> (INFO) NRN Output >>> Finished saving results in 0.002883 seconds\n", + " jNeuroML >> (INFO) NRN Output >>> Done\n", + " jNeuroML >> (INFO) Exit value for running NEURON: 0\n", + " jNeuroML >> \n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pynml.run_lems_with_jneuroml_neuron(\n", + " lems_simulation_file, max_memory=\"2G\", nogui=True, plot=False\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot the recorded data" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Generating plot: Spike times\n", + "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib64/python3.10/site-packages/pyneuroml/plot/Plot.py:174: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n", + " plt.plot(\n", + "pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/example_izhikevich2007network_sim-spikes.png of plot: Spike times\n", + "pyNeuroML >>> INFO - Saved image to example_izhikevich2007network_sim-spikes.png of plot: Spike times\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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o6qrk3L/CaiWFqm+vnflQB7kQR5u5UAe5OFKHp2Fal4WLlzo+aPSJ510kq6++urAcb/97W9r2LBhuuKKKwLtt2jRImWz2Y6X109CJaWmRsr9x7czGWnChN6VA3mQB3m4lQN5kIcreXQWqnl54oknNGfOnILr58yZo8ceeyxQzLq6Ot11111auHChtm3bpi1btmjLli1qbm7WRx99pC1btmjnzp159+3Xr58qKyu7vIqtulq66662Eyq1/ffOO9uW96YcyIM8yMOtHMiDPFzJo7OUMZ1+t7+l/v376/bbb9dXv/rVvOvvvvtuXXnlldqzZ491zF//+tc67bTTPLe58sorrX4CqampSVVVVcpms0VvZBob2z5KmzCh505sKeRAHuRBHm7lQB7kUQp52L5/h2pePv7xj+uLX/yivv/97+ddf9VVV+nBBx/UX/7yF+uYO3bs0IYNG7ot//a3v61du3bptttu0/jx4zVp0iTfWD3ZvAAAgHASbV4uueQS/exnP9NvfvMbTZkypcu6jRs36pRTTtF5552n1atXB888x6mnnqodO3boD3/4g/U+NC8AALjH9v27T5jgS5cu1RNPPKFp06bpnHPO0cSJEyVJf/jDH/Rf//VfGjlypJYuXRoucwAAAA+hPnmRpO3bt+sb3/iGHn300Y4fm66srNQ//MM/aNmyZRo1alSsiQbBJy8AALgn0a+NOjPG6N1335UkjRgxouPfOOpJNC8AALgn0a+NOkulUho5cmTUMAAAAFZC/Z4XAACAnkLzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzAgAAnELzElJjo/T0023/LaVY5RDbxZyTjO1izknGdjHnJGO7mHOSsV3MOcnYSebco0wZymazRpLJZrOJxK+tNSadNkZq+29tbWnEKofYLuacZGwXc04ytos5JxnbxZyTjO1izknGTjLnpNi+f9O8BNTQcGAytL8ymbblPRmrHGK7mHOSsV3MOcnYLuacZGwXc04ytos5Jxk7yZyTZPv+zddGAdXVSa2tXZe1tEj19T0bqxxiu5hzkrFdzDnJ2C7mnGRsF3NOMraLOScZO8mcSwHNS0A1NVI6p2qZjDRhQs/GKofYLuacZGwXc04ytos5JxnbxZyTjO1izknGTjLnklCkT4KKqhjPvGQyBz6Gi/rMS1yxyiG2izknGdvFnJOM7WLOScZ2MeckY7uYc5Kxk8w5Kbbv3yljjOnpBipuTU1NqqqqUjabVWVlZSJjNDa2ffw2YYJUXV06scohtos5JxnbxZyTjO1izknGdjHnJGO7mHOSsZPMOQm27980LwAAoCTYvn/zzAsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHAKzQsAAHBKSTUvL7/8si6//HJNnDhRFRUVGjNmjObOnatNmzb1dGoAAKBE9OnpBDpbsWKFnnvuOZ133nmaPHmy/vKXv2jVqlU67rjj9MILL+iYY47p6RQBAEAPSxljTE8n0e7555/XCSecoIMOOqhjWV1dnSZNmqQ5c+bogQcesIrT1NSkqqoqZbNZVVZWJpWuGhulujqppkaqri79uMUcg2PoPWOUwzEUYwyOofeMwTGEZ/3+bRxw3HHHmeOOO856+2w2aySZbDabWE61tcak08ZIbf+trS3tuMUcg2PoPWOUwzEUYwyOofeMwTFEY/v+XfLNS2trq/n4xz9uZs2aVXCb5uZmk81mO14NDQ2JNi8NDQdObPsrk2lbXopxizkGx9B7xiiHYyjGGBxD7xmDY4jOtnkpqQd281mzZo3efvttzZs3r+A2y5cvV1VVVcdr9OjRieZUVye1tnZd1tIi1deXZtxijsEx9J4xyuEYijEGx9B7xuAYiqekm5c33nhDX/va1zRjxgzNnz+/4HaLFi1SNpvteDU0NCSaV02NlM6pXCYjTZhQmnGLOQbH0HvGKIdjKMYYHEPvGYNjKKLifBAU3Pbt2824cePM6NGjzdtvvx1o32I985LJHPhILc5nXpKIW8wxOIbeM0Y5HEMxxuAYes8YHEM0tu/fJfXTRu2y2axOPfVUbd26Vc8++6yOPvroQPsX86eN6uvbOtK4f9ooibjFHINj6D1jlMMxFGMMjqH3jMExhGf7/l1yzUtzc7NmzZqlV155RU899ZRmzJgROEaxmhcAABAf2/fvkvoldS0tLZo3b55++9vf6tFHHw3VuAAAgPJWUs3L1VdfrZ///Oc6++yztXPnzm6/lO7CCy/socwAAECpKKmvjU499VQ988wzBdfbpsrXRgAAuMfJr41+/etf93QKAACgxJX073kBAADIRfMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMCAACcQvMSQGOj9PTTbf8t5r69IU4p5kQc93Iq1zilmFO5xinFnMo1TiSmDGWzWSPJZLPZ2GLW1hqTThsjtf23trY4+/aGOKWYE3Hcy6lc45RiTuUapxRzKtc4hdi+f9O8WGhoOHCy2l+ZTNvyJPftDXFKMSfiuJdTucYpxZzKNU4p5lSucbzYvn/ztZGFujqptbXrspYWqb4+2X17Q5xSzIk47uVUrnFKMadyjVOKOZVrnDjQvFioqZHSOZXKZKQJE5LdtzfEKcWciONeTuUapxRzKtc4pZhTucaJRXwf9pSOpJ55yWQOfEwW9JmXsPv2hjilmBNx3MupXOOUYk7lGqcUcyrXOIXYvn+njDGmB3qmRDU1NamqqkrZbFaVlZWxxW1sbPt4bMIEqbq6ePv2hjilmBNx3MupXOOUYk7lGqcUcyrXOPnYvn/TvAAAgJJg+/7NMy8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApNC8AAMApJde87Nu3T9dff71GjRqlAQMGaPr06Vq/fn1PpwUAAEpEyTUvF198sW699VZdcMEFuu2225TJZPS5z31OGzZs6OnUAABACUgZY0xPJ9Hu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vLz66qs6/PDDu/0jUdOmTZMkvfbaa3n3a21t1e9//3udcMIJ3dZNmzZNb775pnbt2hV7vuUgbM0L+ctf/iJJOvjgg2PJrxxFrfnWrVt18803a8WKFRowYEBSaZaVKDX/5S9/qalTp+qHP/yhRowYocGDB+vQQw/VqlWrkkzZeVFqfuqpp+p///d/tXjxYtXX1+vNN9/U0qVL9bvf/U7XXXddkmn3aq+++qqOO+64bv8i9LRp07Rnzx5t2rQplnHK7l+V3r59uw499NBuy9uXbdu2Le9+O3fu1L59+3z3PeKII2LMtjyErXkhK1asUCaT0Zw5c2LJrxxFrfnVV1+tKVOm6Pzzz08kv3IUtubvv/++duzYoeeee06/+tWvdMMNN2jMmDFavXq1rrjiCvXt21cLFixINHdXRZnnixcv1ubNm3XTTTfpe9/7niRp4MCBWrdunc4999xkEoa2b9+uU045pdvyzuds0qRJkccpu+Zl7969ef+dhf79+3esL7SfpFD79nZha57Pgw8+qHvuuUfXXXedampqYsux3ESp+dNPP61169bpxRdfTCy/chS25rt375Ykvffee/rJT36iefPmSZLmzJmjSZMm6Xvf+x7NSwFR5nm/fv10+OGHa86cOZo9e7ZaWlp011136cILL9T69ev1qU99KrG8e7M43w+8lF3zMmDAAO3bt6/b8ubm5o71hfaTFGrf3i5szXM9++yzuuSSS3TmmWfqpptuijXHchO25vv379fChQv1j//4j5o6dWqiOZabqPeWvn37dvk0MZ1Oa968ebrhhhu0detWjRkzJoGs3Rbl3nL55ZfrhRde0MaNGzu+wpg7d64mTpyoK6+8kuY9IXG9H/gpu2deDj30UG3fvr3b8vZlo0aNyrvfsGHD1K9fv1D79nZha97Z//zP/+icc87RMccco4cfflh9+pRdXx2rsDW/77779Kc//UkLFizQli1bOl6StGvXLm3ZskV79uxJLG+XRbm39O/fX8OHD1cmk+mybuTIkZLavlpCd2Fr/uGHH+qee+7R5z//+S7PXvTt21ef/exn9bvf/U4ffvhhMkn3cnG8H9gou+bl2GOP1aZNm9TU1NRleXuXfeyxx+bdL51Oa9KkSfrd737Xbd2LL76ocePGafDgwbHnWw7C1rzdm2++qbPOOksjR47UY489pkGDBiWVatkIW/OtW7fqo48+0kknnaTDDjus4yW1NTaHHXaYnnzyyURzd1WUe8uxxx6rd999t9sbZvszGyNGjIg/4TIQtubvvfee9u/fr5aWlm7rPvroI7W2tuZdh+iOPfZYbdy4Ua2trV2Wv/jiixo4cKAOP/zweAaK5WeWSsgLL7zQ7fcCNDc3mwkTJnT58bg///nP5vXXX++y780332wkmZdffrlj2RtvvGEymYy5/vrrk0/eUVFqvn37djNu3DgzatQos3nz5mKl7LywNX/99dfNI4880u0lyXzuc58zjzzyiNm2bVtRj8UVUeb5ypUrjSRz1113dSzbu3evGTdunDn66KOTT95RYWu+f/9+M2TIEHP44Yebffv2dSzftWuXqa6uNkceeWRxDqAMeP2o9LZt28zrr79uPvzww45lP/nJT7r9npd3333XDBkyxMybNy+2vMqueTGm7efM+/TpY6699lpz5513mhNPPNH06dPHPPPMMx3bzJw50+T2bk1NTWb8+PFm5MiR5l//9V/NypUrzejRo82oUaPMO++8U+zDcErYmn/yk580ksx1111n7r///i6vJ598stiH4ZSwNc9H/J4XK2FrvmfPHjNx4kTTt29fc80115gf/vCHZurUqSaTyZjHHnus2IfhlLA1/973vmckmSlTppiVK1ea73//++aoo44ykswDDzxQ7MNwzu23326WLl1q/vmf/9lIMrNnzzZLly41S5cuNR988IExxpj58+cbSV3+x3P//v3mU5/6lBk0aJBZsmSJ+bd/+zczceJEM3jwYPPGG2/Ell9ZNi979+4111xzjTnkkENMv379zNSpU80TTzzRZZtCN/WGhgYzZ84cU1lZaQYNGmT+/u//3tTV1RUrdWeFrbmkgq+ZM2cW8QjcE2We56J5sROl5v/3f/9n5s+fb4YNG2b69etnpk+f3m1fdBel5mvWrDHTpk0zQ4YMMQMGDDDTp083Dz/8cLFSd9onPvGJgvfm9mYlX/NijDE7d+40l1xyiRk+fLgZOHCgmTlzZpdvNOKQMsaYeL6AAgAASF7ZPbALAADKG80LAABwCs0LAABwCs0LAABwCs0LAABwCs0LAABwCs0LAABwCs0LAABwCs0LAABwCs0LgNiNHTtWF198cU+n0c2//Mu/6Iwzzgi0zx133KExY8Zo3759CWUFICiaFwChPP/887rxxhv1wQcf9HQqVjZv3qza2lp985vfDLTfxRdfrA8//FB33nlnQpkBCIrmBUAozz//vJYsWZK3efnTn/6ku+++u/hJebjtttt02GGH6bTTTgu0X//+/TV//nzdeuut4p+CA0oDzQuA2PXr1099+/bt6TQ6fPTRR1qzZo3mzp0bav+5c+fqz3/+s55++umYMwMQBs0LgMBuvPFGXXvttZKkww47TKlUSqlUSlu2bJHU/ZmXe++9V6lUShs2bNDChQs1YsQIDRkyRAsWLNCHH36oDz74QBdddJGGDh2qoUOH6rrrruv2KUdra6t+8IMfaOLEierfv78+9rGPacGCBXr//fd9892wYYN27Nih008/vdu622+/XRMnTtTAgQM1dOhQnXDCCXrwwQe7bHP88cdr2LBhevTRRwNWCkAS+vR0AgDcM3v2bG3atEkPPfSQVq5cqYMPPliSNGLECM/9rrjiCh1yyCFasmSJXnjhBd11110aMmSInn/+eY0ZM0bLli3TY489pltuuUXHHHOMLrrooo59FyxYoHvvvVdf/vKXtXDhQm3evFmrVq3Sq6++queee87zk57nn39eqVRKU6ZM6bL87rvv1sKFCzVnzhxdeeWVam5u1u9//3u9+OKL+tKXvtRl2+OOO07PPfdc0FIBSIIBgBBuueUWI8ls3ry527pPfOITZv78+R1/X716tZFkzjzzTNPa2tqxfMaMGSaVSpnLLrusY9n+/ftNdXW1mTlzZseyZ5991kgya9as6TLOE088kXd5rgsvvNAMHz682/Jzzz3XTJw40edI21x66aVmwIABVtsCSBZfGwEomksuuUSpVKrj79OnT5cxRpdccknHskwmoxNOOEFvvfVWx7K1a9eqqqpKZ5xxhnbs2NHxOv744zVo0CDfZ1Hee+89DR06tNvyIUOGqLGxUS+//LJv7kOHDtXevXu1Z88em0MFkCCaFwBFM2bMmC5/r6qqkiSNHj262/LOz7LU1dUpm81q5MiRGjFiRJfX7t279c477/iObfL8pND111+vQYMGadq0aaqpqdHXvva1gl8Nte/fufkC0DN45gVA0WQyGevlnZuN1tZWjRw5UmvWrMm7v9+zNsOHD8/7YO9RRx2lP/3pT/rFL36hJ554QuvWrdO///u/6zvf+Y6WLFnSZdv3339fAwcO1IABAzzHApA8mhcAoRTzE4jx48frqaee0kknnRSqeTjyyCO1Zs0aZbPZjk972lVUVGjevHmaN2+ePvzwQ82ePVs33XSTFi1apP79+3dst3nzZh111FGRjwVAdHxtBCCUiooKSSrKb9idO3euWlpatHTp0m7r9u/f75vDjBkzZIzRK6+80mX5e++91+XvBx10kI4++mgZY/TRRx91Wbdx40adeOKJ4Q4AQKz45AVAKMcff7wk6Vvf+pbOP/989e3bV2effXZHUxOnmTNnasGCBVq+fLlee+01zZo1S3379lVdXZ3Wrl2r2267TXPmzCm4/8knn6zhw4frqaee0qc//emO5bNmzdIhhxyik046SR/72Mf0+uuva9WqVfr85z+vwYMHd2z3yiuvaOfOnTr33HNjPzYAwdG8AAhl6tSpWrp0qe644w498cQTam1t1ebNmxNpXqS2fyDx+OOP15133qlvfvOb6tOnj8aOHasLL7xQJ510kue+Bx10kC644AKtXbtWy5Yt61i+YMECrVmzRrfeeqt2796t6upqLVy4UN/+9re77L927VqNGTOmS+MDoOekTL5H8AGgzLz11ls68sgj9fjjj+szn/mM9X779u3T2LFj9Y1vfENXXnllghkCsMUzLwB6hXHjxumSSy7RzTffHGi/1atXq2/fvrrssssSygxAUHzyAgAAnMInLwAAwCk0LwAAwCk0LwAAwCk0LwAAwCk0LwAAwCk0LwAAwCk0LwAAwCk0LwAAwCk0LwAAwCk0LwAAwCn/D1+v3Xk+PT55AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Load the data from the file and plot the spike times\n", + "# using the pynml generate_plot utility function.\n", + "data_array_0 = np.loadtxt(\"%s.0.spikes.dat\" % simulation_id)\n", + "data_array_1 = np.loadtxt(\"%s.1.spikes.dat\" % simulation_id)\n", + "times_0 = data_array_0[:,1]\n", + "times_1 = data_array_1[:,1]\n", + "ids_0 = data_array_0[:,0]\n", + "ids_1 = [id+size0 for id in data_array_1[:,0]]\n", + "pynml.generate_plot(\n", + " [times_0,times_1], [ids_0,ids_1],\n", + " \"Spike times\", show_plot_already=False,\n", + " save_figure_to=\"%s-spikes.png\" % simulation_id,\n", + " xaxis=\"time (s)\", yaxis=\"cell ID\",\n", + " colors=['b','r'],\n", + " linewidths=['0','0'], markers=['.','.'],\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/Userdocs/NML2_examples/NeuroML-DB.ipynb b/_sources/Userdocs/NML2_examples/NeuroML-DB.ipynb new file mode 100644 index 00000000..efe4212b --- /dev/null +++ b/_sources/Userdocs/NML2_examples/NeuroML-DB.ipynb @@ -0,0 +1,1471 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create novel NeuroML models from components on NeuroML-DB\n", + "\n", + "This notebook demonstrates how to access the [NeuroML-DB database](https://neuroml-db.org), extract elements in NeuroML format and use them to create new models" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from pyneuroml import pynml\n", + "import urllib.request, json \n", + "import requests\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1) Search for, download and analyse channels accessed via the NeuroML-DB API\n", + "\n", + "### 1.1) Search in the database for a particular type of channel\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NMLCH000023: NaF Inactivating Fast Sodium, Maex De Schutter 1998\n", + "NMLCH001490: NaTs Fast Inactivating Sodium, Gouwens Berg 2018\n", + "NMLCH001398: NaTa Fast Inactivating Sodium, Hay Hill 2011\n", + "NMLCH000171: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000170: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000169: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000168: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000167: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000166: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000165: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000164: NaP Persistent Noninactivating Sodium, Traub Buhl 2003\n", + "NMLCH000163: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000162: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000161: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000160: NaF Fast Transient Inactivating Sodium, Traub Buhl 2003\n", + "NMLCH000159: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000158: NaF Fast Transient Inactivating Sodium, Traub Contreras 2005\n", + "NMLCH000157: NaF Fast Transient Inactivating Sodium, Traub Buhl 2003\n", + "NMLCH000131: NaF Fast Sodium, Pospischil Toledo-Rodriguez 2008\n", + "NMLCH000111: NaTs Fast Inactivating Sodium, Colbert Pan 2002\n", + "NMLCH000110: NaTa Fast Inactivating Sodium, Colbert Pan 2002\n", + "NMLCH000008: NaF Inactivating Fast Sodium, Maex De Schutter 1998\n" + ] + } + ], + "source": [ + "types = {'cell':'NMLCL','channel':'NMLCH'}\n", + "\n", + "# Helper method for search\n", + "def search_neuromldb(search_term, type=None):\n", + " \n", + " with urllib.request.urlopen('https://neuroml-db.org/api/search?q=%s' % search_term.replace(' ','%20')) as url:\n", + " data = json.load(url)\n", + "\n", + " for l in data:\n", + " if type!=None:\n", + " for type_ in types:\n", + " if type==type_ and not types[type_] in l['Model_ID']:\n", + " data.remove(l)\n", + " if l in data:\n", + " print('%s: %s, %s %s %s'%(l['Model_ID'],l['Name'],l['First_Author'],l['Second_Author'],l['Publication_Year']))\n", + " \n", + " return data\n", + "\n", + "data = search_neuromldb(\"Fast Sodium\", 'channel')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.2) Select one of these results and download it, and browse the contents" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: NMLCH001398.channel.nml\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Channel NaTa_t (in file NaTa_t.channel.nml) has notes: Fast inactivating Na+ current\n", + " \n", + "Comment from original mod file: \n", + ":Reference :Colbert and Pan 2002\n" + ] + } + ], + "source": [ + "# Helper method to retrieve a NeuroML file based on modelID\n", + "def get_model_from_neuromldb(model_id, type):\n", + " \n", + " fname = '%s.%s.nml'%(model_id, type)\n", + "\n", + " url = 'https://neuroml-db.org/render_xml_file?modelID=%s'%model_id\n", + " r = requests.get(url)\n", + " with open(fname , 'wb') as f:\n", + " f.write(r.content)\n", + "\n", + " return pynml.read_neuroml2_file(fname), fname\n", + "\n", + "\n", + "# Choose one of the channels\n", + "chan_model_id = 'NMLCH001398'\n", + "\n", + "na_chan_doc, na_chan_fname_orig = get_model_from_neuromldb(chan_model_id, 'channel')\n", + "\n", + "na_chan = na_chan_doc.ion_channel[0] # select the first/only ion channel in the nml doc\n", + "\n", + "na_chan_fname = '%s.channel.nml'%na_chan.id\n", + "os.rename(na_chan_fname_orig, na_chan_fname) # Rename for clarity\n", + "\n", + "print('Channel %s (in file %s) has notes: %s'%(na_chan.id, na_chan_fname, na_chan.notes))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.3) Plot the time course and steady state of this channel" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading LEMS file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_NaTa_t.xml and running with jNeuroML\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -Djava.awt.headless=true -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_NaTa_t.xml -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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rl2rkpOTTV53YdZGtVEo1EK10KJxmLz9XnhBKVDq229NU5/IlSnbMDk5WUVGRmZbV7pKV3E2/JOu0vP9GimlVIUKFRSgdu7cqZRSKjg4WAHqzTffzFCubdu2ClALFizIsDwiIkJt3rxZpaWlKaWUSk1NVadPn1YxMTFq0KBBClAjR47MMYbLly8rQAHq8uXLGdbt379fHT9+PNM2kZGRql69egpQK1asyOOzzki3b2Ns27ZNv32DBg3UzZs39esSExNVx44dFaCGDRuWp3p17fLv16NVq1b6/X3//fcZ1m3ZskVpNBplb2+vIiIisoyzVatWue5b14apqam5ls3tffakvHx/G3VKUcff359GjRplmU3Wr1+fF198UfpwCZtUaPtx6U4DyBGuQimBBDxs+CcB8/SzmjJlCg4ODsyZM4erV6/mWt7Pz4+2bdtiZ5fxK9LNzY3vvvsOBwcHVq5caXQ8jRs3JjAwMNPycuXKMX36dIB81W8qGo2GBQsWZJg72cXFhcmTJwOwefNmk+4vODiY//znPxmWtWnTho4dO5KWlsa2bdtMur+CZv29zISwgEKZcCUmwqVL2seScIkipEaNGrzyyiv8+OOPTJw4kUWLFhm03e7du9m5cydXr17l1q1beHp6otFocHJy4u7duzx48ABvb2+jYkpKSiIsLIwDBw5w584dkpKSUEoRG6vtN3r27Fmj6jWlgIAA6tWrl2m5rm92ZGSkSff375EOntzfhg0bTL6/giYJlxBZKJQJ17lzkJ4O3t4gR54LJTfciCPO0mEYzQ03s9U9adIklixZwtKlS3n77bd56qmnsi17584devbsSXh4eI51xsTEGJVw7d27l759++qvssuubksLCAjIcrnX4zlYk5KSCnR/jx49Mun+Clq+TikKUVjpEq7LXDbbaY4C9+QI80Z0xhXWT4MGdxv+0WC+v8uyZcsyZswY0tPTmTBhQo5lhw4dSnh4OM2aNSMsLIwbN27w999/k5qailKKsmXLAsYNKpqQkED37t25du0aQ4YMYf/+/dy/f19ft+7IljF1m9q/T6kWtv0VNDnCJUQWSlEKH3yIIooznKEhDS0dUv7JFYqiiBs/fjw//vgjoaGh/PXXX1mWiY+PJzQ0FDs7O0JDQylevDhpaWlER0fr19+6dcvoGP766y9u375Nw4YNmT9/fqb158+f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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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MXDgQNauXVvsdREREQwaNIh69erh5OSEv78///73v/VWVSurc+fOERQUhJeXFw4ODnh5eREUFMSFCxfM7tNSfvvtNxRFwcnJicTExFLb37p1C3t7exRFITIysuIDLKcan2iDZum+Tz75hJiYGDIzM4mPj2fbtm306dOn2Gt27dqFWq1m9uzZBueCgoJMWgFFiFIVnQwpI9pCCFHtXblyhfbt2/Paa69x5swZevTowbBhw2jWrBl//PEH69evN3rdN998Q79+/fjll1946KGHGDx4MElJSXz88cd06tTJ6Kfspdm3bx8PP/wwK1aswMPDg+HDh+Ph4cGKFSto166d1T99f+KJJ/D19SUzM1M3d64kq1atIicnhzZt2tClS5dKiLB87otEW4gqq+iItkzKFUKIai0jI4N+/fpx8uRJZs+ezbVr1wgPD2fNmjXs27eP27dv85///MfguqioKGbMmIGNjQ1btmxh9+7drFu3jvPnz9OnTx/OnDnDiy++WKZY0tPTGTVqFOnp6cyaNYvo6GjWrFlDdHQ0s2bNIi0tjVGjRunNYatsiqIwceJEAIKDg0ttv2zZMgAmTZpUoXFZiiTaQliTQaItpSNCCFGdffLJJ5w+fZrJkyfz/vvvG6xq5uzszCOPPGL0OrVazXPPPcfAgQP12i9duhSVSsWGDRs4ffq0ybEsX76ca9eu4efnx4cffqh37sMPP8TPz4/Lly+zcuXKsr1JCwsKCsLGxoYjR45w4sSJYttFRkby999/Y29vT2BgYCVGaD5JtIWwpqKlIzKiLYQQ1VZOTg7ff/89AG+++abJ12VnZ7NlyxYAxo4da3C+WbNm9OjRA4CwsDCT+9W2HT16NCqVfsqnUql45plnANi4caPJfe7atQtFUejVqxdZWVnMmTMHPz8/HB0d8fb25u233yYzMxOApKQk3njjDZo3b46joyM+Pj7Mnj2b3NxcvT69vLwYMGAAUPKotvbckCFDqFevnskxW5Mk2kJYlYxoCyFETXH06FHu3LlD48aNadmyJSdOnGDOnDm88MILzJw5ky1btpCfn29wXUxMDOnp6QB06tTJaN/a41FRUSbHo21ryT61srOzGTBgAF9//TUPPPAA/fr1Izk5mc8//5yAgAASEhLo2rUrK1eupEOHDvTs2ZObN28yZ84cpk6datCfthRk9erV5OTkGJzP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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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ALwfKl68OAs1IiKiQjB58mTVXKTKs25UtPAaJhERkQE4duwYlixZAgBYvXo15yItoli4ERER6bm4uDgMGjQIAPDFF1+gdevWEiciqbBwIyIi0nMTJkzAkydP4OnpiYULF0odhyTEwo2IiEiP/fHHH1i5ciUAYO3atbC3t5c4EUmJhRsREZGeevv2LYYMGQIAGDNmDJ8eJRZuRERE+iooKAiRkZH46KOPMG/ePKnjkB5g4UZERKSH9uzZg/Xr10Mmk2HdunWwsbGROhLpAY0Kt7/++gt3797Ns929e/fw119/aXIIIiKiIismJgZDhw4FAIwfPx7e3t4SJyJ9oVHh5uvri++//z7PdgsWLECzZs00OQQREVGRNWrUKLx48QIff/wxZs+eLXUc0iMaXypVTiRPRERE2rNjxw5s2bIFpqamWL9+PaysrKSORHpEp/e4vXnzht9wREREanr58iWGDx8O4P30VnXr1pU4Eekbtecqffr0aab/T0hIyLJMKT09HTdu3MDhw4dRvnz5giUkIiIqAoQQGD58OKKjo/Hpp5/i22+/lToS6SG1CzdPT0/IZDLV/+/cuRM7d+7MdRshBPr166d5OiIioiJi8+bNCAkJgZmZGdavXw8LCwupI5EeUrtw8/DwUBVuT58+hY2NDVxcXLJta2FhAblcju7du6tO+RIREVH2nj9/jlGjRgEAvvnmG9SoUUPaQKS31C7cHj9+rPq3iYkJevTogTVr1ugiExERUZEhhMDQoUPx5s0b1K5dG1OmTJE6EukxtQu3D61duxYfffSRtrMQEREVOevWrcP+/fthYWGB9evXw9zcXOpIpMc0KtwGDBig7RxERERFTkREBIKCggAAs2bNQpUqVaQNRHpPo8LtQwqFAjExMXj37l2ObTw8PAp6GCIiIqMihMCQIUMQFxeHBg0aYMKECVJHIgOg8Thu58+fR7t27WBvbw9XV1d4eXll+1WuXDlt5i2Q7du3w9fXF05OTrC1tUX16tWxYMECpKWlabS/ixcvokePHihVqhSsrKzg5eWF0aNH4+XLl1pOTkRExmbFihU4fPgwrKyssG7dOpiamkodiQyARmfc/v77bzRv3lx1ls3JyQkODg5aDaZtQUFBCA4OhpmZGZo3bw47OzscO3YMkyZNwt69e3H48GFYW1urvb8dO3agT58+SE9PR926deHl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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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EhEREZHVYHJKRERERFaDySkRERERWQ0mp0RERERkNZicUpOQmJiIDz74ACNGjIC/vz8kEgkkEgmuX79ea9ny8nIsXboU3bt3h6urK5o1a4YBAwZg69attZbdsmULBgwYgGbNmsHV1RXdu3fHJ598goqKClNcFv2Xuj2r+5k4cWK1ZVUqFVatWoU+ffrA3d0d7u7u6NOnD1avXg3OF204fK9Yt2nTptX6PistLdVb9o8//sD48ePh6+sLJycnhIaGYu7cucjNzW3gq2jcLl++jBUrVmDatGno2rUr7O3tIZFI8NFHH9VaNikpCdHR0fD29oazszM6dOiAt99+G0VFRTWWu3r1KqZNm4aAgAA4OjoiICAA06ZNQ1paWr2uhbP1qUnw8vJCQUGBzvbs7GwEBARUW664uBiDBw/G0aNH4eXlhYEDB6KoqAi//vorKisrsWDBAnz66ad6y86bNw/Lly+Hvb09Bg4cCDc3N/z666+4f/8++vfvj71798LZ2dlk19iUSSQSAMDUqVP17u/Tpw9efvllne1KpRITJkzAtm3b4OLigqioKAAPPqhLSkowfvx4bNq0CVIp/443J75XrN+0adPw7bffIiIiAm3bttV7zNdffw0HBwetbVu3bsWkSZNQWVmJXr16ITQ0FCdPnkRaWhp8fX1x+PDhauujulG/jx724Ycf4p133qm23LJlyzB//nxIJBJERkbC19cXycnJuHXrFsLDw3H48GF4e3vrlDty5AiGDBmC4uJidO7cGV26dMG5c+dw/vx5uLq6IikpCX379jXuYgRREzB9+nSxZMkS8csvv4jc3FwBQAAQ2dnZNZZ79dVXBQDRtWtXcefOHc32kydPCjc3NwFA7Nq1S6dcQkKCACDc3NzEH3/8odl+584d0bVrVwFALFiwwHQX2MSp27Ouli1bJgCI1q1bi7S0NM32tLQ04e/vLwCIFStWmDJUegjfK7Zh6tSpAoBYt26dwWVu3LghXFxcBACxatUqzfbKykrx/PPPCwCiV69eQqVSmSHipufrr78WCxcuFD/88IO4ePGieOGFFwQA8eGHH1Zb5tSpU0IikQg7OzuRmJio2a5QKERUVJQAIGJiYnTKKRQKzWdkbGys1r7Y2FgBQAQGBori4mKjroXJKTVJhiSn+fn5QiaTCQDi8OHDOvs//PBDAUD07dtXZ1+vXr0E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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from pyneuroml.analysis.NML2ChannelAnalysis import run\n", + "\n", + "na_erev = 50 # mV\n", + "run(channel_files=[na_chan_fname], ivCurve=True, erev=na_erev, clampDelay=5, clampDuration=10, duration=20)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.4) Find a Potassium channel" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NMLCH000113: K Fast Noninactivating Potassium, Rettig Wunder 1992\n", + "NMLCH001627: KDr Fast Delayed Rectifier Potassium , Bezaire Raikov 2016\n", + "NMLCH001611: KDr Fast Delayed Rectifier Potassium, Bezaire Raikov 2016\n", + "NMLCH001609: KDr Fast Delayed Rectifier Potassium , Bezaire Raikov 2016\n", + "NMLCH001549: K Fast Potassium, Boyle Cohen 2008\n", + "NMLCH001529: KT Fast Inactivating Potassium, Gouwens Berg 2018\n", + "NMLCH001465: K Fast Noninactivating Potassium, Gouwens Berg 2018\n", + "NMLCH001400: KTst Fast Inactivating Potassium, Hay Hill 2011\n", + "NMLCH001394: K Fast Noninactivating Potassium, Hay Hill 2011\n", + "NMLCH000156: IM M Type Potassium, Traub Buhl 2003\n", + "NMLCH000155: KDr Delayed Rectifier Potassium, Traub Buhl 2003\n", + "NMLCH000154: KDr Delayed Rectifier Potassium Channel for Fast Spiking (FS) Interneurons, Traub Contreras 2005\n", + "NMLCH000153: KCa BK Type Fast Calcium Dependent Potassium, Traub Buhl 2003\n", + "NMLCH000152: KCa BK Type Fast Calcium Dependent Potassium, Traub Buhl 2003\n", + "NMLCH000151: KCa AHP Type Calcium Dependent Potassium, Traub Buhl 2003\n", + "NMLCH000149: KCa Slow AHP Type Calcium Dependent Potassium, Traub Buhl 2003\n", + "NMLCH000148: IA A Type Potassium, Traub Buhl 2003\n", + "NMLCH000146: K2 Type Slowly Activating and Inactivating Potassium, Traub Buhl 2003\n", + "NMLCH000123: K Fast Potassium, Korngreen Sakmann 2000\n", + "NMLCH000108: KTst Fast Inactivating Potassium, Korngreen Sakmann 2000\n" + ] + } + ], + "source": [ + "data = search_neuromldb(\"Fast Potassium\", 'channel')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: NMLCH000113.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading LEMS file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_SKv3_1.xml and running with jNeuroML\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -Djava.awt.headless=true -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/LEMS_Test_SKv3_1.xml -nogui -I '') in directory: .\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Channel SKv3_1 (in file SKv3_1.channel.nml) has notes: Fast, non inactivating K+ current\n", + " \n", + "Comment from original mod file: \n", + ":Reference : :\t\tCharacterization of a Shaw-related potassium channel family in rat brain, The EMBO Journal, vol.11, no.7,2473-2486 (1992)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Command completed successfully!\n" + ] + }, + { + "data": { + "image/png": "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pYjevXszePBg6+PWIQSPPPIIX331FT4+PrRr145OnTrh5ubG3Llzuffee603x4iI3G531CXFO4JhwK0z3yYnY4mLg9hYyO/zOPn6gsWS52p69OhB+fLl+fPPPwkJCaFNmza0b9+e4OBgGjdunKOE5+eff2batGlcv36dZ555hvfffx9LJrEVK1aMXr16sXDhQr788ksmTJiQrszcuXMBGDp0aIZ1LFq0iDVr1pCUlMSFCxf4+eefiY+PZ9CgQdY7c/OjadOm8cUXXzBw4EDrtvHjxzN9+nQef/xx/vzzT9asWUP79u0Bcy3Qvn378u233zJ16lQ+/fTTbM/RsmVLWrZsyaZNm4iNjeWdd97JdL68hQsX8uCDD6ZZxsswDD766COefvppnnjiCfbt25dpW4qIOIwhThcVFWUARlRUVLZlExISjD///NNISEjIuMD164Zhpl2u97h+3W7v6eHDh42mTZsaQLpHgwYNjI8++shISkpKd1ybNm3SlA0ODjZSUlKyPd/69esNwKhZs2a6fb/99psBGGXKlDESExMzPH7MmDFpzmuxWIyxY8caV69eNQ4dOpRhrLYaPHiwARhvvPGGzXWkvk99+vRJt+/q1avW1/H888+n2797924DMKpUqZKrc1aqVMkAjJMnT9oUc7NmzQzAOHDgQJrtqa9l48aNGR732muvGYDx2muv5fhct35OExISjOXLl2f+mZV8T23o2hzZfrn5/tYlRSmQatasya+//sr27dv517/+RadOnaw9W7/99hsjR46kc+fOJCQkZHh88+bN8fDwYM+ePYwcORLDMLI83/3330/lypU5cuQIv/zyS5p9qb1bgwYNso7L+qf33nsPwzC4efMmhw8f5uWXX2b27NkEBwfn+NKbM3Tt2jXdtuLFi1OiRIlM91evXh2A8+fPOySmY8eOMXPmTJ599lmGDRvGkCFDGDJkiHVsX2ZjuUREHEmXFAsaX1/437qQYF7COXbsGNWqVcv/S8Nks3C3LZo0aUKTJk0A89LS3r17efvtt1m8eDHr1q3j/fff5/nnn093XEhICC+++CJ9+vTh448/Jjk5mU8++STTS1EWi4UhQ4YQGhrK3LlzadasGWCu4bVw4UIg88uJt/Ly8qJmzZq88cYb1KtXj0ceeYSJEyfSpUsXW98Ch0odL/dPhQsX5urVqxnuT71BJT4+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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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y1OnQvnyLg1HJC9KuERExPOkp5vH20pPh549oX9/V0ckkiclXCIi4nmmTYM9e8yXEj/4QJcSxe0p4RIREc9y8iT885/m5bfegjJlXBuPiA2UcImIiGcZPhySkqBpUxgyxNXRiNhECZeIiHiOlSvhyy/No8hPnw5e+hkTz6B/qSIi4hnS0v4cZ+vvf4d77nFtPCL5oIRLREQ8w4wZsH8/hIfD2LGujkYkX5RwiYiI+7t6FV591bw8fjyUKOHScETySwmXiIi4vzffhAsXoEYNeOopV0cjkm9KuERExL39/ju8+655efJk8PFxaTgi9lDCJSIi7u211+DGDWjTBjp3dnU0InZRwiUiIu7r0CH47DPz8r/+pRHlxWMp4RIREfc1fjxkZJjPbDVp4upoROymhEtERNzTL7/AF1+Yl197zbWxiBSQEi4REXFP48aBYUC3bnDffa6ORqRAlHCJiIj7+eUXWLjQvDx+vGtjEXEAJVwiIuJ+Jk0yP3fvril85LaghEtERNzL8eN/9t0aPdq1sYg4iBIuERFxL++8A+np5nG3GjVydTQiDqGES0RE3MeFC+ZJqkFnt+S2ooRLRETcx9SpkJIC9etD27aujkbEYZRwiYiIe7h2zZxwgfnslkaVl9uI2ydcCxcupHXr1oSFhREcHEzdunWZNGkSaWlp+a4rOTmZCRMm0KBBA4oVK4avry/lypWjS5cuLFu2zAnRi4iIzebOhYsXoXJl6NHD1dGIOJRbT7k+fPhwpkyZgo+PD23atCEkJIR169YxatQoli9fzurVqwkMDLSprosXL9KyZUt++eUXQkJCaNasGSVKlODQoUOsWLGCFStWMGzYMKZMmeLkdyUiItkYBrz3nnl56FDw9nZtPCIO5rZnuJYuXcqUKVMICQlh27ZtrFq1ikWLFnHw4EHq1KlDXFwcY8eOtbm+1157jV9++YX77ruP33//nVWrVjF//nx27drFihUr8PHx4b333mPr1q1OfFciIpKj776DH3+EoCB4/HFXRyPicG6bcL355psAjB49mvr161vXh4eH88EHHwAwdepUrl69alN969atA2DUqFGULFkyy7bOnTvzwAMPALBly5YCxy4iIvlkObs1cCCUKOHSUEScwS0TrpMnT7Jjxw4ABgwYkG17ixYtiIyMJDU1ldjYWJvqDAgIsKlceHi47YGKiEjB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O3bk+PHjjBo1ijZt2nDt2rV81Xfjxg369OlDt27dWLt2LXfffTe9evWidu3aHD58mPfee8/uWEVEioQzZ2DvXvNyu3aujUXEg9h1SfHNN9/k+vXrLFy4kB49egDQt2/fLGX8/Py499572Wv5YubT0qVLmTJlCiEhIWzcuJH69esDcOHCBdq0aUNcXBxjx45l8uTJNtf55JNPsnDhQrp168aMGTMIDw+3bsvMzGT79u12xSoiUmSsXm1+vu8+KFPGtbGIeBC7znCtX7+eunXrWpOt3ERERHD69Gm7AnvzzTcBGD16tDXZAggPD+eDDz4AYOrUqVy9etWm+r799ltmz55N7dq1WbBgQZZkC8DLy4smTZrYFauISJGhy4kidrEr4Tp//jzVbJioND09neTk5HzXf/LkSXbs2AHAgAEDsm1v0aIFkZGRpKamEhsba1Od77//PmC+TOnr65vvmEREirzMTFizxryshEskX+y6pFi8eHFOnjx5y3JHjhyhjB2nnPfs2QNAyZIlqVy5co5lGjRoQHx8PHv27KF///551peRkcG3334LQMuWLTlz5gzz5s3jwIED+Pv7U69ePXr27ElISEi+YxURKTJ274YLF8wjyzdt6upoRDyKXQlX/fr1+e677zh+/DhRUVE5lvnpp5/Yu3cv3bt3z3f9R48eBci1boDIyMgsZfNy5MgRkpKSANi6dSvPPvus9bXFSy+9xLx582jTpk2+4xURKRIsw0FER4OuFIjki10J1xNPPMHq1avp378/ixYtoly5clm2X7hwgSeeeALDMHjiiSfyXX9iYiIAwcHBuZaxnI1KSEi4ZX0XL160Lg8ZMoRmzZoxefJkatSoweHDh3n55ZeJjY3l4YcfZvfu3VStWjXXulJTU0lNTbX1rdjE8h7S0tIKNNxFTiz1ObpeKRxqP893O7Wh96pVeAEZbduSeRu8H1vdTm1YVDmrDfNTn10JV69evejduzcLFy7krrvuonnz5gBs2rSJrl27smHDBpKSknjkkUfo4AbX+W8esqJChQqsWrUKf39/AOrWrcuyZcu49957+emnn5g4cSKffPJJrnVNmDCB8ePHOyXO1atXExQU5JS611j6XYhHUvt5Pk9vQ+/r1+m8ZQsA6729Sbax/+ztxNPbUBzfhikpKTaXtXuk+blz51KlShXeffdd1q5dC8DBgwc5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+OmnnwoU49SpU+nbty+1atUiPDwcX19fSpYsScuWLZk2bZpDRq8/cOAA77//PjExMdSpU8c6bpun/f5WqlQJk8nk0OkDT548yWOPPUZkZCS1a9fGx8eHmJgYh9WfH3ad4YqOjubgwYNZ1r366qvUqVOHhQsXcunSJWrWrMnw4cOJiopySKAiIlIILGe3KlSAgADXxpKHxYsXM2DAAFJTUylVqhTNmzendOnSXL58mR9++IFp06Yxb948evbsaXOdV65c4cEHH2Tz5s1UqVKFNWvWUKlSpQLdrTZx4kTOnj3L3XffTePGjSlWrBgnT55ky5YtfP/998yZM4e1a9cSEhJi9zE+/PBDpkyZYvf+tyvDMOjRowfbt2+nVq1a3HfffZQsWZIWLVq4JB6HDqPao0cPevTo4cgqRUSkMHlA/62zZ88yaNAgUlNTGTlyJG+88QYBf0kOd+3axZdffmlznWfOnKFDhw78+OOP1K1bl1WrVjmkD/K8efO49957syVUx48fp3379mzbto1//etfTJgwwe5j1K5dmxdffJF69epRv3593nzzTebMmVPQ0Avdt99+S1paGhUqVHBIfb///jvbt28nKiqK3bt3c/ToUapWreqywWvtSrhmz55NlSpVaNasWZ7ltm7dym+//cbAgQPtCk5ERAqRYXhEwvX111+TlJRE+fLlmTx5co5l7rvvPu677z6b6jt27Bjt2rXj0KFD3H///Sxfvtx6931B5XY2JSoqildeeYWBAweyevXqAiVcTzzxRJbXnjrf41133eXQ+o4fPw5A5cqVHT5Njz3sapWYmBg+/vjjW5b75JNPGDx4sD2HEBGRwnb+PCQlga8vuPG0bGfPngXMg2wX1M8//0zz5s05dOgQDz74IKtWrcqWbP33v/+lZs2adO7cOdd6Ll68iL+/P35+fpy3caJvSxLg7+9v/xtwEktftw0bNrB161YefPBBSpUqRWhoKK1ateL777+3ll25ciXR0dGEhYUREhJCu3bt2L17d76PmVsfrptj+eGHH+jRowfh4eH4+/tTq1Yt3n777SxjZh07dgyTyUSrVq0A2LhxIz4+PtSsWRMfHx+H9hHLD6emwY4eNExERJzI0n8rKgrc4IxAbix9g3/66Se+/fZbu+vZvn07LVu2tN5Rv3TpUgIDA7OV69u3LwEBAaxdu5aTJ0/mWNfcuXO5ceMGDz30kE2J4Llz53jrrbcAcp21xR2sWLGC+++/n9OnT9OuXTuqVKnCd999R7t27di8eTPTpk3jwQcf5Pr167Rv354KFSqwdu1aWrVqxaFDhxway6pVq2jcuDH79++nXbt2NG3alN9++40XX3yRF154wVouJCSEQYMG0aFDBwDKli3LwIED6datGwMHDixQf7mCcOo36ty5cwQFBTnzECIiRYthQEqKc+r+5Re4cQPKlTNPXO1oQUEOmZexW7duVKhQgZMnT9KuXTtatWpFdHQ09evXp2HDhjYlPJs2beLtt98mKSmJ559/nilTpuQ64GXx4sVp164dy5cvZ86cOYwePTpbmZkzZwLkelVn7ty5rF69mvT0dE6fPs2mTZtITU1l0KBBjBgxIh/vvnC9/fbbzJ49m0cffdS6buTIkbzzzjs8/vjjnDx5ktWrVxMdHQ2Yp6bq27cvixYt4q233mLGjBkOi2XixIlMnz6dv/3tb9Z169ato23btkydOpUXX3yRiIgIwsPDmTVrFhs2bGDVqlXUqFGDTz/9lIMHD3pGH67vvvsuy+szZ85kW2eRnp7Ozz//zOrVq6lTp07BIhQRkT+lpICz/4degP5EeUpKguDgAlcTEhLCt99+y6BBg9i2bRsbNmxgw4YN1u333nsvf/vb33jyySdz/XFdu3YtAPXr188z2bLo0aMHy5cvZ9asWdkSrr1797Jnzx7KlStHx44dc9x/+/btfPbZZ9bXJpOJF154gVdffdX182bmoVevXlmSLYBXXnmFd955hwMHDvDSSy9Zky0Ab29vXn75ZRYtWlSgs4856dGjR5ZkC6BNmzZ06NCBlStXsn79eh577DGHHtORbE64LNdQLVatWsWqVavy3McwDJ555hn7oxMREclB9erV2bp1K9u3b2fFihVs27aN3bt3c/78eX744QeeeeYZFi1axIoVK3JMaJo1a8aOHTvYvXs3zzzzDB9++GGeSVfjxo2pVKkSBw4cYMuWLTRt2tS6zXJ2a+DAgbl2zn733Xd59913SU1N5dixY3z++ee8/fbbLF68mNjYWGrVqlXAT8Q5cuq3VrJkSUqVKsXFixdz3F61alUg+3R/BfXQQw/luL5mzZqsXLky18u97sLmhKtly5bWf4wbN26kTJkyWSawvpmfnx8RERH07Nkzz06GIiKST0FB5jNF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JBAZGUl8fDzFihVzaN3ifGo/z6c29HxqQ8/nrDY0DIPExETKly+Pl1fevbR0hssNeHl5ERER4dRjFCtWTH8oPJjaz/OpDT2f2tDzOaMNb3Vmy0Kd5kVEREScTAmXiIiIiJMp4RIRERFxMiVcIiIiIk6mhEtERETEyZRwiYiIiDiZEi4RERERJ1PCJSIiIuJkSrhEREREnEwJl4iIiIiTKeESERERcTIlXCIiIiJOpoRLRERExMmUcImIiIg4mRIuERERESdTwiUiIiLiZEq4RERERJxMCZeIiIiIkynhEhEREXEyJVy3OX9/f1599VX8/f1dHYrYQe3n+dSGnk9t6PncoQ1NhmEYLju6iIiISBGgM1wiIiIiTqaES0RERMTJlHCJiIiIOJkSLhEREREnU8LloWJjYxk3bhwPPfQQ5cuXx2QyYTKZOHHixC33vXHjBm+99RZ169YlODiYsLAwWrduzZdffnnLfRcuXEjr1q0JCwsjODiYunXrMmnSJNLS0hzxtuQPlvbM7dGvX79c983MzOSjjz6icePGhIaGEhoaSuPGjfnvf/+L7pEpXPq+uK+YmJhbfs+uX7+e4767du2id+/elC1bloCAACpXrszzzz/PuXPnCvld3P4OHDjA+++/T0xMDHXq1MHHxweTycQbb7xxy33Xrl1L586dCQ8PJzAwkBo1avDKK6+QlJSU536HDh0iJiaGiIgI/P39iYiIICYmhiNHjhToveguRQ9VokQJrl69mm19fHw8ERERue6XkpJCu3bt2Lx5MyVKlKBNmzYkJSWxbt060tPTGTlyJJMnT85x3+HDhzNlyhR8fHxo06YNISEhrFu3jitXrtCiRQtWr15NYGCgw95jUWYymQAYNGhQjtsbN27MM888k219RkYGffr0YfHixQQFBREdHQ2Y//Bcu3aN3r17M2/ePLy89H8tZ9P3xb3FxMTw2Wef0bx5c6pUqZJjmRkzZuDr65tl3Zdffkn//v1JT0+nYcOGVK5cmZ07d3LkyBHKli1LXFxcrvVJ/lm+R3/1+uuv889//jPX/f7zn/8wYsQITCYT999/P2XLluX777/nzJkzVK9enbi4OMLDw7Ptt2nTJtq3b09KSgp33303tWvX5qeffuLnn38mODiYtWvX0qRJE/vejCEeafDgwcabb75prFy50jh37pwBGIARHx+f535/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YqcGDRpw8eJFvvrqqxy3b968mf3799OwYcNCjkzENSZMmMCvv/5K9+7dXR0KL7zwAgEBAYwePdrpxxo8eDBeXl7s2LGDn3/+Oc+ys2fPJj09nbp163LfffdZ1w8dOpTSpUszZswYUlNTnR2yuIASLhE7Pf7440Du/6v95JNPspQTud3dcccd1KhRg+LFi7s0jjVr1vDTTz/RrVs3SpUq5fTjRUVF0bZtW+DWZ7lmzpwJZP+7EBAQwIABAzh9+jTz5893TqDiUkq4ROxUp04dGjRowOrVqzl58mSWbUlJSSxYsICIiAjat2+fZz3p6el8/PHHtG7dmpIlS+Lv70/lypV55plniI+Pz1Z+w4YNmEwmWrduTWpqKuPHj6datWoEBAQQFRXFqFGjuH79OmDuG/Liiy9y5513EhAQQKVKlRg3bhzp6el5xrR371569OhB6dKlCQwM5J577mHKlClkZGRkKztu3DhMJhPjxo3j+PHjDBkyhMjISHx9fbNcflq8eDFPPPEEtWvXJiwsjICAACpXrszjjz/OgQMHcozj5j5BR48e5bHHHqNcuXL4+/tz11138c9//jPPswG7du3ikUceISoqCn9/f0qWLEmHDh2sl3Ty4+b+RBs3bqR9+/aULFmSoKAgGjVqxJw5c3LdNz09nenTp9OsWTOKFy9OQEAAVatWZdiwYdn+7Vgu3f3+++8AVK5c2doPMKf+TKdOnWLEiBHUrFmToKAgQkNDadiwIVOnTs2xne35TCtVqmS9bPbZZ59liad169Y51n2zxMREZsyYQY8ePahatSrBwcEEBwdTp04dXnnlFa5cuXKLTz9/pk6dao0nJzdfrv3mm29o3bo1xYsXJywsjC5durBv3z5r2blz59K0aVNCQ0MpUaIEPXr04PDhw9nqfOKJJwD4/PPPSUtLy/G4W7du5ddff8Xf359HH30023ZLvNOmTcvP2xVPYYhIvlSsWNEAjO+//9744IMPDMB44403spT55JNPDMB45ZVXjKNHjxqA4e3tna2uhIQEo3Xr1gZghISEGK1atTJ69eplVK9e3QCMUqVKGbt3786yz/r16w3AaNq0qdGqVSujWLFiRteuXY0uXboYxYsXNwCjS5cuxsWLF43q1asbpUuXNnr27Gm0b9/eCAgIMADj6aefzhbLoEGDDMB45plnjICAAKNSpUpG3759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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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BQCMGTNG7SwCRGWRmTaN3nvvPURERBQ6zxkREZGmfvvtN1y8eBFWVlbK+5CJSMtEbd68eXBycoKfnx8ePXqk65iIiKiM+e677wAAw4YNg6urq4GjITIeWl36DAoKQv369XHo0CHUrVsXXl5ehU54q3jUmoiI6L+ioqIQFhYGAJg4caJhgyEyMlolaps2bVI+jZOdnY0LFy7gwoULausyUSMiosKsWLECeXl56Ny5Mxo2bGjocIiMitZLSBEREZVUcnIyfvzxRwCc4JZIHa0StREjRug6DiIiKoN++uknpKSk4K233sK7775r6HCIjI5WDxMQERGVVG5uLoKDgwG8ujfNzIxfSUT/xXcFEREZxL59+/Do0SNUqFABw4cPN3Q4REZJq0uf77//vsZ1+TABERGps2zZMgCc4JaoMFo/9VkYxROhQggmakRElM/vv/+O3377DVZWVvjkk08MHQ6R0dLpU595eXl49OgRwsPDcfnyZUycOBGNGjUqUYBERPTmUUxwO2TIELi5uRk4GiLjpZenPufPn4/PPvsM69evx9WrV7UKjIiI3kyPHj3Cnj17AHBKDqKi6O1hgkWLFsHBwQFz587V1y6IiMgEKSa47dixI6+6EBVBb4mahYUFmjRpghMnTuhrF0REZGJSUlKwfv16ADybRqQJvU7PkZGRgZcvX+pzF0REZEI2bNiA5ORk1K1bF926dTN0OERGT2+J2q1btxAZGQkPDw997YKIiEyIXC7nBLdExaTVwwQhISEFlqWkpODWrVvYsmULMjMz4e/vr3VwRET05ti/fz+ioqJQvnx5BAQEGDocIpOgVaIWGBionCtNHSEEAKB3796YPXu2dpEREdEbRTHB7ccffwxbW1sDR0NkGrRK1AICAgpM1KysrFClShV06tQJrVq1KlFwRET0Zrh48SLOnTsHS0tLTnBLVAx6WZmAiIjodYoJbgcPHgx3d3cDR0NkOngnJxER6VV0dDR2794NgFNyEBWXxmfULl26hNjYWLz11luoXbt2oXXv3r2L27dvw93dHd7e3iUOkoiITNeKFSsgl8vh6+sLLy8vQ4dDZFI0StTi4uLQsWNHODg44I8//iiyvrOzM8aOHYv09HQ8ePAA5cqVK2GYRERkilJTU7Fu3ToAwOTJkw0cDZHp0ejS588//4zU1FQsWLAAFStWLLJ+xYoVsXDh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EtHR0ZBKpejevbtGfSqWeFLXX2pqKg4ePAgA+T7AFe0OHDig9vKnor834YPfFL+MGXPpMdWkx9zcHL6+vhgyZAgXUSci06PFPG2loqAlpOLi4gpcQiosLEzUrVtXdOjQIV9/ry8htW7dOuX23Nxc5WS3RS0hFRAQUCaWkOLKBKXD1FYmoNLF8TN9HEPTxwlvC9GnTx+MHz8e33//PVq0aIGOHTvCzs4OJ0+eRGJiInx8fPD555+rtElKSsKdO3fUPhnm7u6OTZs2YciQIfjwww/x008/oVq1arh06RIePHgAV1dXbNu2Te3lqO3bt6NNmzYICQlBZGQkmjZtiqioKFy8eBEWFhYICQmBm5ubXl+P0mRubo527dohLS0N7dq1M4kzEIqzJqbEFGMmIqLSZZSXPhWCg4Oxc+dOtGzZEufPn0d4eDhkMhmWLFmCX3/9FTY2NsXqb8CAAbhw4QL8/Pzw4MED7N27F3K5HJ988gn+/PNP5X1s/1W3bl389ddf+OSTTyCXy7F3717lJZ8LFy4oL48SERER6ZLRnlFTGDhwIAYOHKhR3cDAQAQGBhZa55133kFoaGix43Bzc8PKlSuxcuXKYrclIiIi0oZRn1EjIiIiKsuYqBEREREZKSZqREREREaKiRoRERGRkWKiRkRERGSkmKgRERERGSmjn56DCib+/+LYycnJOu87JycH6enpSE5O5mLCJopjaNo4fqaPY2j69DWGiu9txfd4YZiombCUlBQAgIeHh4EjISIiouJKSUmBk5NToXUkQpN0joxSXl4enj59CgcHh3xLX5VUcnIyPDw8EB0dDUdHR532TaWDY2jaOH6mj2No+vQ1hkIIpKSkwN3dHWZmhd+FxjNqJszMzAwymUyv+3B0dOQHjInjGJo2jp/p4xiaPn2MYVFn0hT4MAERERGRkWKiRkRERGSkmKgRERERGSkmakRERERGiokaERERkZFiokZERERkpJioERERERkpJmpERERERoqJGhEREZGRYqJGREREZKSYqBEREREZKSZqREREREaKiRoRERGRkWKiRkRERGSkmKgRERERGSkmakRERERGiokaERERkZFiokZERERkpJioERERERkpJmqkllQqxbx58yCVSg0dCmmJY2jaOH6mj2No+oxhDCVCCGGwvRMRERFRgXhGjYiIiMhIMVEjIiIiMlJM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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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U6IWHR2t7ziIiIi0duzYMVy4cAF2dnb4/PPPjR0OkcHolKhVrFhR33EQERFpTXE0bdCgQXBzczNyNESGo9PNBERERMZy69Yt7N69GwAwevRo4wZDZGA6L8oOAElJSfj9999x8uRJPHv2DG3btsXXX38NALh58ybu3buHli1bwtbWVi/BEhERLV68GEIIdO7cGTVq1DB2OEQGpXOiduDAAfTr1w8vXryAEAISiQQVKlRQlt+4cQPdunXDpk2b0KtXL70ES0REJdvz58+xZs0aAJzglkoGnU59Xrt2Dd27d0diYiKGDh2KLVu2QAihUqdDhw6wt7fHH3/8oZdAiYiIVq1ahbS0NLz33nto06aNscMhMjidjqjNnTsXGRkZ2LZtGwIDAwEAvXv3VqljY2ODevXq4eLFi0WPkoiISrysrCz89NNPADjBLZUcOh1RO3LkCOrWratM0vIik8kQFxenU2BERESv27ZtGx49eoTy5cujb9++xg6HqFjolKg9e/YM1atXL7BeTk4OUlNTddkFERGRkhACCxYsAPBqglupVGrkiIiKh06JmouLCx4+fFhgvbt376JcuXK67IKIiEgpKioK58+fh62tLb744gtjh0NUbHRK1Bo0aIBz587luWwUAFy+fBkXL15EkyZNdA4OeHWo28/PD66urnBwcEDdunUxf/58ZGdnF6ofHx8fSCSSAn9mzZql0u7o0aMFtlmxYkWRHiMREeVPMcFtcHAwypYta+RoiIqPTjcTfPLJJzhw4AD69u2L8PBwuLu7q5THx8fjk08+gRACn3zyic7BjR49GosXL4aVlRXatGkDR0dH/PXXXxg/fjx2796NAwcOwM7OTqu+goKCEB8fr7Hs+fPnyskTW7durbFO+fLl0bFjR41lnMeHiMhwbt++rZxBgBPcUkmjU6IWFBSEnj17Ytu2bahSpQp8fX0BACdOnEBAQACOHj2KlJQU9O/fHx06dNApsJ07d2Lx4sVwdHTEsWPH0KBBAwCvksA2bdrg+PHjmDp1Kn744Qet+suv3vz587F7925Ur14dLVq00FinZs2aWLt2baEfBxERFc1PP/0EIQQ+/PBDvPvuu8YOh6hY6byE1MaNGzFx4kQAwKFDhwC8WtZjz549yMrKQmhoaJESm7lz5wIAJkyYoEzSAMDNzQ3Lly8HACxduhSJiYk670Nh9erV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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Download one of these\n", + "\n", + "k_chan_doc, k_chan_fname_orig = get_model_from_neuromldb('NMLCH000113', 'channel')\n", + "\n", + "k_chan = k_chan_doc.ion_channel[0] # select the first ion channel in the nml doc\n", + "\n", + "k_chan_fname = '%s.channel.nml'%k_chan.id\n", + "os.rename(k_chan_fname_orig, k_chan_fname) # Rename for clarity\n", + "\n", + "print('Channel %s (in file %s) has notes: %s'%(k_chan.id, k_chan_fname, k_chan.notes))\n", + "\n", + "k_erev = -77\n", + "run(channel_files=[k_chan_fname], ivCurve=True, erev=k_erev)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.5) Find a passive (leak) current\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NMLCH000015: Passive Leak, Maex De Schutter 1998\n", + "NMLCH001623: Passive Leak, Bezaire Raikov 2016\n", + "NMLCH001601: Passive Leak, Smith Smith 2013\n", + "NMLCH001590: Passive Leak, Prinz Bucher 2004\n", + "NMLCH001545: Passive Leak, Boyle Cohen 2008\n", + "NMLCH001471: Passive Leak, Gouwens Berg 2018\n", + "NMLCH001427: Passive Leak, Hodgkin Huxley 1952\n", + "NMLCH001403: Passive Leak, Hay Hill 2011\n", + "NMLCH000172: Passive Leak, Traub Contreras 2005\n", + "NMLCH000130: Passive Leak, Pospischil Toledo-Rodriguez 2008\n", + "NMLCH000114: Passive Leak, Hodgkin Huxley 1952\n", + "NMLCH000095: Passive Leak, Vervaeke Lorincz 2010\n", + "NMLCH000027: Passive Leak, De Schutter Bower 1994\n", + "NMLCH000024: Passive Leak, Maex De Schutter 1998\n", + "NMLCH000016: Passive Leak, Maex De Schutter 1998\n", + "NMLCH000007: Passive Leak, Migliore Ferrante 2005\n", + "NMLCH000139: Passive Leak, Hodgkin Huxley 1952\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: NMLCH000015.channel.nml\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Channel GranPassiveCond has notes: Simple leak conductance for Granule cell\n" + ] + } + ], + "source": [ + "data = search_neuromldb(\"Leak\", 'channel')\n", + "\n", + "pas_chan_doc, pas_chan_fname = get_model_from_neuromldb(data[0]['Model_ID'], 'channel')\n", + "pas_chan = pas_chan_doc.ion_channel[0] # select the first ion channel in the nml doc\n", + "\n", + "print('Channel %s has notes: %s'%(pas_chan.id, pas_chan.notes))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2) Create a new cell model using these channels\n", + "\n", + "### 2.1) Create the Cell object, add channels and save to file" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning: Segment group all already exists.\n", + "Warning: Segment group soma_group already exists.\n", + "Written cell file to: TestCell.cell.nml\n", + "It's valid!\n", + "*******************************************************\n", + "* NeuroMLDocument: TestCell\n", + "*\n", + "*\n", + "* Cell: novel_cell\n", + "* \n", + "* Parent segment: None (root segment)\n", + "* (0.0, 0.0, 0.0), diam 17.841242um -> (0.0, 0.0, 0.0), diam 17.841242um; seg length: 0.0 um\n", + "* Surface area: 1000.0000939925986 um2, volume: 2973.540612824116 um3\n", + "* Total length of 1 segment: 0.0 um; total area: 1000.0000939925986 um2\n", + "* \n", + "* SegmentGroup: soma_group,\t1 member(s),\t0 included group(s);\tcontains 1 segment, id: 0\n", + "* SegmentGroup: all,\t1 member(s),\t0 included group(s);\tcontains 1 segment, id: 0\n", + "* \n", + "* Channel density: NaTa_t_chans on all;\tconductance of 150 mS_per_cm2 through ion chan NaTa_t with ion non_specific, erev: 50 mV\n", + "* Channel is on ,\ttotal conductance: 1500.0 S_per_m2 x 1.0000000939925986e-09 m2 = 1.500000140988898e-06 S (1500000.140988898 pS)\n", + "* Channel density: SKv3_1_chans on all;\tconductance of 36 mS_per_cm2 through ion chan SKv3_1 with ion non_specific, erev: -77 mV\n", + "* Channel is on ,\ttotal conductance: 360.0 S_per_m2 x 1.0000000939925986e-09 m2 = 3.600000338373355e-07 S (360000.0338373355 pS)\n", + "* Channel density: GranPassiveCond_chans on all;\tconductance of 0.3 mS_per_cm2 through ion chan GranPassiveCond with ion non_specific, erev: -65 mV\n", + "* Channel is on ,\ttotal conductance: 3.0 S_per_m2 x 1.0000000939925986e-09 m2 = 3.000000281977796e-09 S (3000.000281977796 pS)\n", + "* \n", + "* Specific capacitance on all: 1.0 uF_per_cm2\n", + "* Capacitance of ,\ttotal capacitance: 0.01 F_per_m2 x 1.0000000939925986e-09 m2 = 1.0000000939925987e-11 F (10.000000939925988 pF)\n", + "*\n", + "*******************************************************\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: morphology has already been assigned. Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.\n", + " warnings.warn(\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: biophysical_properties has already been assigned. Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.\n", + " warnings.warn(\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: intracellular_properties has already been assigned. Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.\n", + " warnings.warn(\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/neuroml/nml/generatedssupersuper.py:176: UserWarning: membrane_properties has already been assigned. Use `force=True` to overwrite. Hint: you can make changes to the already added object as required without needing to re-add it because only references to the objects are added, not their values.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from neuroml import *\n", + "from neuroml.utils import component_factory\n", + "import neuroml.writers as writers\n", + "\n", + "\n", + "nml_doc = NeuroMLDocument(id=\"TestCell\")\n", + "\n", + "cell = component_factory(\"Cell\", id=\"novel_cell\")\n", + "nml_doc.add(cell)\n", + "\n", + "cell.add_segment(prox=[0,0,0,17.841242], \n", + " dist=[0,0,0,17.841242], \n", + " seg_type='soma')\n", + "\n", + "cell.set_resistivity('0.03 kohm_cm')\n", + "cell.set_init_memb_potential('-65mV')\n", + "cell.set_specific_capacitance('1.0 uF_per_cm2')\n", + "cell.set_spike_thresh('0mV')\n", + "\n", + "\n", + "cell.add_channel_density(nml_doc,\n", + " cd_id='%s_chans'%na_chan.id,\n", + " ion_channel=na_chan.id,\n", + " cond_density='150 mS_per_cm2',\n", + " ion_chan_def_file=na_chan_fname,\n", + " erev=\"%s mV\"%na_erev)\n", + "\n", + "cell.add_channel_density(nml_doc,\n", + " cd_id='%s_chans'%k_chan.id,\n", + " ion_channel=k_chan.id,\n", + " cond_density='36 mS_per_cm2',\n", + " ion_chan_def_file=k_chan_fname,\n", + " erev=\"%s mV\"%k_erev)\n", + "\n", + "cell.add_channel_density(nml_doc,\n", + " cd_id='%s_chans'%pas_chan.id,\n", + " ion_channel=pas_chan.id,\n", + " cond_density='0.3 mS_per_cm2',\n", + " ion_chan_def_file=pas_chan_fname,\n", + " erev=\"-65 mV\")\n", + "\n", + "\n", + "\n", + "cell_file = \"%s.cell.nml\"%nml_doc.id\n", + "writers.NeuroMLWriter.write(nml_doc, cell_file)\n", + "\n", + "\n", + "print(\"Written cell file to: \" + cell_file)\n", + "\n", + "from neuroml.utils import validate_neuroml2\n", + "\n", + "validate_neuroml2(cell_file)\n", + "\n", + "#!cat TestCell.cell.nml\n", + "\n", + "\n", + "pynml.summary(nml_doc, verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2) Generate a plot of the actvity of the cell under current clamp input" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/TestCell.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NMLCH000015.channel.nml\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" -validate iv_novel_cell.net.nml ) in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/iv_novel_cell.net.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/TestCell.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NMLCH000015.channel.nml\n", + "pyNeuroML >>> INFO - Loading LEMS file: LEMS_iv_novel_cell.xml and running with jNeuroML\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -Djava.awt.headless=true -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" LEMS_iv_novel_cell.xml -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/fromnumeric.py:3432: RuntimeWarning: Mean of empty slice.\n", + " return _methods._mean(a, axis=axis, dtype=dtype,\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/_methods.py:190: RuntimeWarning: invalid value encountered in double_scalars\n", + " ret = ret.dtype.type(ret / rcount)\n", + "pyNeuroML >>> INFO - Generating plot: Membrane potential traces for: TestCell.cell.nml\n", + "pyNeuroML >>> INFO - Generating plot: Firing frequency versus injected current for: TestCell.cell.nml\n" + ] + }, + { + "data": { + "image/png": "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2Ey82g8Py7K4/vrrkZ6ebvVHkZDw/odQEk5dXR0BQOrq6hJtSlLR1NREtmzZQpqamhJtStx48803CQDy9ttvC9uqqqpITk4OmT17dtTjr732WpKamkr27t0rbFu7di0BQP75z38K27Zs2UIaGhokxx4+fJgUFBSQM844w4JPomTOnDlk+PDh5MknnyTp6emksbHRluscz5SUlBAA5JFHHhG2tbS0kN69e5PTTz896vEPP/wwAUA2bdokbNuxYwdxOp1k4cKFkn3LysoIy7KEEELS09PJZZddZs2H0OCuu+4iHTt2JO+88w5hGIbs2bPH1usdj8Sz/fA8//zzpEOHDuTGG28kAEh1dXXsH0QFM/0PPwatWrWKLF26lHz44YeKffSO31TZolCSiFWrVqFTp0648MILhW0FBQWYOXMm3nvvvaizYd555x1MmzYNxcXFwraJEyeiX79+eOutt4RtJ598sqJYbIcOHTBmzBjs2LEjqp333HMPGIZBaWkp5s6di5ycHGRnZ+Pyyy9Hc3OzYv+Wlha8++67mDVrFmbOnImWlha89957Ua9DMcaqVavgdDoxb948YVtKSgquvPJK/O9//8P+/fujHn/qqafi1FNPFbb1798fZ511lqT9ANwSJmbXjFu+fDkYhsE333yDm2++WQiZX3DBBYqQN89rr72G6dOnY9q0acjOzsZrr71m6toUbeLZfgCgtrYWd9xxB+69917k5OTotrM99j/U2aK0KwghaPYFkuo/EsMMFTlbt27F8OHDFYVcR4wYgebmZvz222+ax5aXl6OqqgqnnHKK4r0RI0Zg69atUa9/8OBB5Ofn67Z35syZaGhowIMPPoiZM2di+fLlWLx4sWK/999/H42NjZg1axY6d+6MM888M6lCQYQQsM3NSfOf2Ta1detW9OvXD1lZWZLtI0aMAABs27ZN81iWZfHjjz9qtp/ff/8dDQ0NpuzS4vrrr8cPP/yAu+++G9deey0++OADLFiwQLFfSUkJSktLMXv2bHg8Hlx44YXJ1358waT5r720nzvvvBOdO3fGX/7yF1P2tqf+55ivs0U5tmjxBzHwrk8TbYaEX+79A9I81vyUKisrMXbsWMV2fgH1iooKDBkyRPNY8b7y42tra9HW1qa53MRXX32F//3vf7jjjjt023vSSSfhpZdeEl7X1NTgpZdewsMPPyzZ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1NmiUCgUCoVCsRHqbFEoFAqFQqHYCHW2KBQKhUKhUGyEOlsUCoVCoVAoNkKdLQqFQqFQKBQboc4WhUKhUCgUio1QZ4tCoVAoFArFRqizRaFQKBQKhWIj1NmiUJKMo0ePYt68eSgoKEB6ejrGjx+P77//XvfxO3bswJQpU5CRkYG8vDxceumlqK6uVuz3wAMP4LzzzkOnTp3AMAzuueceCz+FkmAwiKKiIjAMg48//tjWax3PtLW14fbbb0dRURFSU1MxcuRIrF27Vvfx5eXlmDlzJnJycpCVlYU//vGP2L17t2Sf/fv3Y/HixRgxYgRyc3ORn5+PM888E5999pnVH0fCiBEjwDAMnn/+eVuvczwTj/YDAAzDqP730EMPWflxBBLd/1Bni0JJIliWxdSpU/Haa69hwYIFWLp0KaqqqnDmmWdi165dUY8/cOAAxo4di9LSUixZsgS33HILPvroI0yaNAk+n0+y7x133IHNmzfjpJNOsuvjSPjiiy9QWVmJHj16YOXKlXG55vHI3Llz8dhjj+Hiiy/Gk08+CafTiXPOOQdff/111GMbGxsxfvx4fPnll1i0aBEWL16MrVu3Yty4caipqRH2e++99/Dwww+jT58+uP/++3HnnXeioaEBkyZNwrJly2z5XLt27cLmzZtp+7GZeLQfnkmTJuHVV1+V/Hfuuefa8bES3/8Qkxw8eJCsXLmS/O1vfyOXXHIJmTp1KrnkkkvI3/72N/Laa6+RgwcPmj31cUddXR0BQOrq6hJtSlLR1NREtmzZQpqamhJtStx48803CQDy9ttvC9uqqqpITk4OmT17dtTjr732WpKamkr27t0rbFu7di0BQP75z39K9t2zZw8hhJDq6moCgNx9992WfAYt5syZQ4YPH06efPJJkp6eThobG2293vFISUkJAUAeeeQRYVtLSwvp3bs3Of3006Me//DDDxMAZNOmTcK2HTt2EKfTSRYuXChs2759O6murpYc29raSvr370+6du1qwSdRctddd5GOHTuSd955hzAMI7RfinXEq/0QQggAct1111lnfBTM9D/8GLRq1SqydOlS8uGHHyr20Tt+G3K2fD4fefXVV8lpp51GHA4HcTgchGEYxX/8e6effjpZsWIF8fl8Ri5z3EGdLXWOR2drxowZpFOnTiQYDEq2z5s3j6SlpZHW1taIx3fs2JHM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dg0KxQ5MFTXdvXs3xo0bh4qKCqH8gxaJUMXq6upw9tln4+jRo/jqq69QVFQkvMeHD/lwopjKykrk5eVpqloUipXMnTsXq1atwl//+lf07dsXy5cvxznnnIN169Zh9OjREY9tbGzE+PHjUVdXh0WLFsHtduPxxx/HuHHjsG3bNnTo0MFye1euXIkePXpg06ZNKC0tRZ8+fSy/BiV24tGuWlpa8PPPP+Occ85Bjx494HA4sHHjRtx0000oKSnBa6+9Zvnn2rVrFzZv3owePXpg5cqVuPbaay2/BoViG8QEF154IWEYhpxxxhlk9erV5KeffiJlZWWa/8WTlpYWMmbMGJKWlkY2btyouk9BQQGZMWOGYnu/fv3IhAkT7DZRQV1dHQFA6urq4n7tZKapqYls2bKFNDU1JdoUyykpKSEAyCOPPCJsa2lpIb179yann3561OMffvhhAoBs2rRJ2LZjxw7idDrJwoULLbd39+7dBABZvXo1KSgoIPfcc4/l16DETqLb1YIFCwgAUllZae4DROCuu+4iHTt2JO+88w5hGIbs2bPH8mtQKGL4MWjVqlVk6dKl5MMPP1Tso3f8NuVs5eTkkO7du5OWlhYzh9tGIBAg5513HnG5XOSjjz7S3O+aa64hqampZN++fcK2zz77jAAgzz//fDxMlUCdLXWOZWfr1ltvJU6nU/GdL1myhACQtE01Tj31VHLqqacqtk+ePJn07t076vUBkOuuu468++67ZNCgQcTj8ZCBAweSjz/+WHX/++67j+Tm5pK2tjZy7bXXkr59+0a9BiX+JLpd/f3vfycAyI4dOyLut2zZMgKAfP311+Smm24i+fn5JC0tjZx//vmkqqpK9Zg+ffqQ+fPnk7a2NpKTk0MeeOCBqPZQKLFgpbNlermekSNHCgnlycLf/vY3vP/++zj77LNRW1uLFStWSP7jWbRoEdLS0jB+/Hg8/fTTePDBBzFjxgwMGTIEl19+eQI/AeV4YevWrejXr58iX2/EiBEAgG3btmkey7IsfvzxR83yJb///ruwEHwkvv76a8yfPx+zZs3C0qVL0draij/96U+oqalR7Lty5UpceOGF8Hg8mD17thDSoSQX8W5XPp8Phw8fxv79+/Huu+/i73//O7p37647xHz99dfjhx9+wN13341rr70WH3zwARYsWKDYr6SkBKWlpZg9ezY8Hg8uvPBCrFy5Utc1KJRkwFTO1uDBg1FbW2u1LTHDdyQffPABPvjgA8X7l1xyCQCgW7du+PLLL3HzzTfj//2//wePx4OpU6fi0UcfpflaSQ4hBC2BlkSbISHVlWo4N7GyslKz/AgAVFRUaB7LlyeJdvwJJ5wQ0YYdO3bgl19+ESaxjB8/HkOHDsXrr78uGfC+++477Ny5E08//TQAYPTo0ejatStWrlyJU089NconbR8QQhCwuH5eLLi8XlP5rvFuV6tXr8bs2bOF16eccgpefvlluFz6hpYOHTpgzZo1wmdlWRZPPfUU6urqkJ2dLey3YsUKdOvWDWeccQYAYNasWXj55Zexbds2DBs2TNe1KJREYsrZWrBgAS6//HJs375dWG8wGVi/fr3ufQcNGoRPP/3UPmMottASaMHI15JrNlzJn0uQ5k4zdIxWeRFx+ZFIxwLRy5dEY+LEiZLZwieeeCKysrIUM89WrlyJTp06Yfz48QC4SS8XXXQRVqxYgUcffVSY6dueCbS14anLpifaDIEb/r0KbhORg3i3q/Hjx2Pt2rU4evQoPv/8c/zwww9oamrSbe+8efMkTuWYMWPw+OOPY+/evTjxxBMBAIFAAG+++SYuu+wyYd8JEyagY8eOWLlyJXW2KO0CU2HEP//5z7jxxhsxYcIE/POf/8S+ffustotCOaZJTU01XX4k1vIlPOLlqnhyc3Nx5MgR4XUwGMQbb7yB8ePHY8+ePSgtLUVpaSlGjhyJQ4cO4fPPP496HUr8iHe76tSpEyZOnIjp06fj+eefx7Rp0zBp0iQcPHhQl73yNpibmwsAkja4Zs0aVFdXY8SIEUL727NnD8aPH4/XX38dLMvquhaFkkhMKVsAt17iJ598gvnz50fcj2EYBAIBs5ehUCSkulJR8ueSRJshIdUV3bGRU1hYiPLycsV2viSJuFyJHL48iVb5kmjH82gpUkRUzuWLL75AZWUl3njjDbzxxhuKfVeuXInJkydHvVay4/J6ccO/VyXaDAGXyXSGRLer6dOn4//+7//w3nvv4S9/+UtUe/W0QT43a+bMmar7fvnll4LqSqEkK6acre3bt2PcuHE4evRo1Dpb0d6nUIzAMIzhkF0yMmzYMKxbtw719fWSZOaSkhLhfS0cDgeGDBmCLVu2KN4rKSlBr169kJmZaYmdK1euRMeOHfHss88q3lu9ejXeffdd/OMf/9ClpCUzDMOYCtslG4luV3yYsa6uzoT1SpqamvDee+/hoosuwvTpyjDvDTfcgJUrV1Jni5L0mAojLly4EEeOHMH06dPx/fffo6GhASzLav5HoVCkTJ8+HcFgEC+88IKwra2tDcuWLcPIkSMlyzft27cPO3fuVBy/efNmycD466+/4osvvsCMGTMssbGlpQWrV6/GtGnTMH36dMV/CxYsQENDA95//31LrkeJnXi1q8OHD6s+SL/44osAoDqj0QzvvvsumpqacN1116m2wWnTpuGdd95RDX1SKMmEKWXrm2++wQknnIA33nij3a6bSKEkkpEjR2LGjBlYuHAhqqqq0KdPH/z73/9GWVkZXnrpJcm+c+bMwZdffikZ3ObPn49//etfmDp1Km655Ra43W489thj6NSpE/72t79ZYuP777+PhoYGnHfeearvn3baaSgoKMDKlStx0UUXWXJNSmzEq12tWLEC//jHP3D++eejV69eaGhowKeffoq1a9fi3HPPxYQJEyz5PCtXrkSHDh0watQo1ffPO+88/Otf/8JHH32ECy+80JJrUih2YMrZYlkWw4YNo44WhRIDr7zyCu688068+uqrOHLkCE488UR8+OGHGDt2bNRjMzMzsX79etx00024//77wbIszjzzTDz++OMoKCiwxL6VK1ciJSUFkyZNUn3f4XBg6tSpWLlyJWpqamxZIohinHi0q9GjR2Pjxo14/fXXcejQIbhcLpxwwgl47LHHcP3111vyOaqqqvDZZ59h9uzZmrldZ511FtLS0rBixQrqbFGSGoaYSKoaP348gsEgNmzYYIdNxx319fXIzs5GXV0dXZRaRHNzM3bs2IEBAwYgLa3952lRKBQKpf3Aj0FlZWXYvXs3Bg4ciKlTp0r20Tt+m8rZuu222/DNN98YqmtFoVAoFAqFcjxiKow4aNAg3H777TjnnHNw44034uyzz0ZxcTEcDnXfTa2eD4VCoVAoFMrxgClnq0ePHmAYBoQQLF26FEuXLtXcl9bZolAoFAqFcjxjytkqLi6myfEUCoVCoVAoOjDlbJWVlVlsBoVCoVAoFMqxiakEeQqFQqFQKBSKPqizRUl66CoEFAqFQok3Vo49upytiooKSy5m1XkoxwcejwcA0NjYmGBLKBQKhXK8wY89fr8/5nPpytnq27cvrr/+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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAHMCAYAAADI/py4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABdXUlEQVR4nO3dd1gUV/s+8HvpHcUCKGCNvSAajUTAHhW7YIuvGDV2sSSaGGOLGk2MRo1RY4kaC6uCPTY0NLsmYo0tigpiiSJFirCc3x/+2K+Eti67DLt7f67L63qZOTtzPwdeeDIze1YmhBAgIiIiokIZSR2AiIiISBewaSIiIiJSAZsmIiIiIhWwaSIiIiJSAZsmIiIiIhWwaSIiIiJSAZsmIiIiIhWwaSIiIiJSgYnUAfRJdnY2Hj16BFtbW8hkMqnjEBERkQqEEEhOTkalSpVgZFTw9SQ2TRr06NEjuLq6Sh2DiIiI1PDw4UO4uLgUuJ9NkwbZ2toCeDPpdnZ2GjtuZmYmjh49io4dO8LU1FRjx9Ulhj4Hhl4/wDlg/YZdP8A50Gb9SUlJcHV1Vf4dLwibJg3KuSVnZ2en8abJysoKdnZ2Bvl/FIBzYOj1A5wD1m/Y9QOcg5Kov6hHa/ggOBEREZEK2DQRERERqYBNExEREZEK2DQRERERqYBNExEREZEK2DQRERERqYBNExEREZEK2DQRERERqYBNExEREZEK2DQRERFRqaZQKBAREYHIyEhERERAoVBIkoNNExEREZVau3btQtWqVdGhQwcsWbIEHTp0QNWqVbFr164Sz8KmiYiIiEqlXbt2wc/PD7Gxsbm2x8XFwc/Pr8QbJzZNREREVOooFApMmDABQog8+3K2TZw4sURv1bFpIiIiolInKioqzxWmtwkh8PDhQ0RFRZVYJjZNREREVOrEx8drdJwmsGkiIiKiUsfZ2Vmj4zSBTRMRERGVOl5eXihfvnyB+2UyGVxdXeHl5VVimdg0ERERUalz8+ZNpKamAnjTIL0t5+ulS5fC2Ni4xDKxaSIiIqJS5fHjx+jSpQtq1KiBzZs3o3Llyrn2u7i4IDg4GL179y7RXCYlejYiIiKiQqSmpqJ79+54/fo1fv/9d7i6umLAgAEICwvDoUOH0LlzZ7Rp06ZErzDlYNNEREREpYJCocDHH3+M69evIzIyEq6urgAAY2Nj+Pj44NWrV/Dx8ZGkYQLYNBEREVEpMXXqVOzbtw979+6Fh4eH1HHyYNNEREREklu5ciWWLFmC5cuXo2vXrlLHyRcfBCciIiJJ/f777xg/fjwmTJiA8ePHSx2nQGyaiIiISDIXL15Ev3790K1bNyxevFjqOIVi00RERESSiI2NRdeuXVG3bl1s3bpVsge8VcWmiYiIiEpcUlISfH19YWJigv3798Pa2lrqSEXig+BERERUorKystCvXz/ExMTg1KlTcHJykjqSStg0ERERUYkRQmDcuHE4duwYDh06hPr160sdSWVsmoiIiKjELF68GL/88gvWrVuH9u3bSx3nnfCZJiIiIioRISEhmDJlCqZNm4Zhw4ZJHeedsWkiIiIirTtz5gwGDRqEfv36Yd68eVLHUQubJiIiItKqu3fvonv37mjatCk2btwIIyPdbD90MzURERHphISEBPj6+sLe3h579uyBhYWF1JHUxgfBiYiISCtev36N3r174+nTpzhz5gzKly8vdaRiYdNEREREGieEwKeffopTp07h+PHjeO+996SOVGxsmoiIiEjj5s6di99++w3btm1Dq1atpI6jEXymiYiIiDRqy5YtmDVrFubOnYsBAwZIHUdj2DQRERGRxkRERGDo0KEYMmQIpk+fLnUcjWLTRERERBpx8+ZN9OrVC15eXvjll18gk8mkjqRRbJqIiIio2J49e4YuXbrA2dkZISEhMDMzkzqSxvFBcCIiIiqWtLQ09OjRA69evcLx48dRpkwZqSNpBZsmIiIiUlt2djYCAgIQHR2NiIgIVK1aVepIWsOmiYiIiNT21VdfITg4GCEhIXj//feljqNVbJqIiIhILWvXrsV3332HxYsXo1evXlLH0bpS+yD47du30b9/f7i4uMDKygp16tTBN998g9TU1FzjTp06hVatWsHKygpOTk4IDAxESkqKRKmJiIgMw5EjRzB69GiMGTMGkyZNkjpOiSiVV5oePnyI5s2bw97eHuPGjYODgwNOnz6NWbNm4c8//8TevXsBANHR0WjXrh3q1q2LJUuWIDY2Fj/88ANu376NQ4cOSVwFERGRfrp8+TL8/f3x0UcfYdmyZXq3tEBBSmXTtHnzZrx8+RInTpxA/fr1AQAjRoxAdnY2fvvtNyQkJKBs2bL46quvULZsWYSHh8POzg4AULVqVXz66ac4evQoOnbs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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{-0.02: 0.0,\n", + " -0.01: 0.0,\n", + " 0.0: 0.0,\n", + " 0.01: 0.0,\n", + " 0.02: 0.0,\n", + " 0.03: 50.0,\n", + " 0.04: 70.0,\n", + " 0.05: 90.0}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pyneuroml.analysis import generate_current_vs_frequency_curve\n", + "\n", + "generate_current_vs_frequency_curve(cell_file,\n", + " cell.id,\n", + " start_amp_nA=-0.02,\n", + " end_amp_nA=0.06,\n", + " step_nA=0.01,\n", + " pre_zero_pulse=20,\n", + " post_zero_pulse=20,\n", + " analysis_duration=100,\n", + " temperature='34degC',\n", + " plot_voltage_traces=True)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3) Search for, download and analyse a complete NeuroML cell\n", + "\n", + "### 3.1) Search for and download the cell\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NMLCL000109: Layer 2/3 Burst Accommodating Martinotti Cell (3), Markram Muller 2015\n", + "NMLCL000395: Layer 6 Burst Non-accommodating Martinotti Cell (4), Markram Muller 2015\n", + "NMLCL000393: Layer 6 Burst Non-accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000345: Layer 4 Burst Non-accommodating Martinotti Cell (4), Markram Muller 2015\n", + "NMLCL000343: Layer 4 Burst Non-accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000315: Layer 2/3 Burst Non-accommodating Martinotti Cell (4), Markram Muller 2015\n", + "NMLCL000313: Layer 2/3 Burst Non-accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000191: Layer 6 Burst Accommodating Martinotti Cell (5), Markram Muller 2015\n", + "NMLCL000190: Layer 6 Burst Accommodating Martinotti Cell (4), Markram Muller 2015\n", + "NMLCL000188: Layer 6 Burst Accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000161: Layer 5 Burst Accommodating Martinotti Cell (5), Markram Muller 2015\n", + "NMLCL000160: Layer 5 Burst Accommodating Martinotti Cell (4), Markram Muller 2015\n", + "NMLCL000158: Layer 5 Burst Accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000157: Layer 5 Burst Accommodating Martinotti Cell (1), Markram Muller 2015\n", + "NMLCL000136: Layer 4 Burst Accommodating Martinotti Cell (5), Markram Muller 2015\n", + "NMLCL000134: Layer 4 Burst Accommodating Martinotti Cell (3), Markram Muller 2015\n", + "NMLCL000133: Layer 4 Burst Accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000111: Layer 2/3 Burst Accommodating Martinotti Cell (5), Markram Muller 2015\n", + "NMLCL000108: Layer 2/3 Burst Accommodating Martinotti Cell (2), Markram Muller 2015\n", + "NMLCL000187: Layer 6 Burst Accommodating Martinotti Cell (1), Markram Muller 2015\n" + ] + } + ], + "source": [ + "data = search_neuromldb(\"Burst Accommodating Martinotti\", 'cell')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model_ID:\tNMLCL000109\n", + "Status:\tCURRENT\n", + "Errors:\tNone\n", + "Status_Timestamp:\t2018-12-24T16:29:21+00:00\n", + "Type:\tCell\n", + "Equations:\t2061\n", + "Runtime_Per_Step:\t0.000510815108024267\n", + "Max_Stable_DT:\t0.0625\n", + "Max_Stable_DT_Error:\t0.969373115260111\n", + "Max_Stable_DT_Benchmark_RunTime:\t4.903825037032964\n", + "Optimal_DT:\t0.00781557069252977\n", + "Optimal_DT_Error:\t0.122802372280653\n", + "Optimal_DT_Benchmark_RunTime:\t39.21518682026722\n", + "Optimal_DT_a:\t0.000968992248062015\n", + "Optimal_DT_b:\t15.8634962901345\n", + "Optimal_DT_c:\t-0.0136485748710791\n", + "CVODE_baseline_step_frequency:\t13111.7719061286\n", + "CVODE_steps_per_spike:\t766.973690134512\n", + "CVODE_Benchmark_RunTime:\t10.615508666396945\n", + "Name:\tLayer 2/3 Burst Accommodating Martinotti Cell (3)\n", + "Directory_Path:\t/var/www/NeuroMLmodels/NMLCL000109\n", + "File_Name:\tbAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "File_Updated:\tNone\n", + "File_MD5_Checksum:\tbcf74ccd8c6840f6c8f7551084c989b7\n", + "File:\t/var/www/NeuroMLmodels/NMLCL000109/bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "Publication_ID:\t6000246\n", + "Upload_Time:\t2016-12-14T14:29:41+00:00\n", + "Notes:\tNone\n", + "ID_Helper:\t175\n", + "Sections:\t40\n", + "Compartments:\t204\n", + "Stability_Range_Low:\tNone\n", + "Stability_Range_High:\tNone\n", + "Is_Passive:\t0\n", + "Is_Intrinsically_Spiking:\t0\n", + "Resting_Voltage:\t-71.2726975181673\n", + "Rheobase_Low:\t0.0469207763671875\n", + "Rheobase_High:\t0.048065185546875\n", + "Threshold_Current_Low:\t0.234375\n", + "Threshold_Current_High:\t0.29296875\n", + "Bias_Voltage:\t-80.0\n", + "Bias_Current:\t-0.0221022438906573\n", + "CVODE_Active:\tNone\n", + "Threshold:\tNone\n", + "Is_GLIF:\t0\n", + "V_Variable:\tNone\n", + "Steady_State_Delay:\tNone\n", + "AP12AmplitudeDrop:\t1.2698800006924\n", + "AP1SSAmplitudeChange:\t2.3903765783198\n", + "AP1Amplitude:\t72.1822400011024\n", + "AP1WidthHalfHeight:\t0.53\n", + "AP1WidthPeakToTrough:\t5.03000000000009\n", + "AP1RateOfChangePeakToTrough:\t-17.8182926253306\n", + "AP1AHPDepth:\t17.4437719043123\n", + "AP2Amplitude:\t70.91236000041\n", + "AP2WidthHalfHeight:\t0.55\n", + "AP2WidthPeakToTrough:\t6.22000000000003\n", + "AP2RateOfChangePeakToTrough:\t-14.2206642462703\n", + "AP2AHPDepth:\t17.5401716113915\n", + "AP12AmplitudeChangePercent:\t-1.75926931704115\n", + "AP12HalfWidthChangePercent:\t3.77358490566034\n", + "AP12RateOfChangePeakToTroughPercentChange:\t-20.1906459541805\n", + "AP12AHPDepthPercentChange:\t0.552631091532312\n", + "InputResistance:\t386.187465741356\n", + "AP1DelayMean:\t20.6200000000001\n", + "AP1DelaySD:\t0.0\n", + "AP2DelayMean:\t72.1300000000001\n", + "AP2DelaySD:\t0.0\n", + "Burst1ISIMean:\t60.255\n", + "Burst1ISISD:\t0.0\n", + "InitialAccommodationMean:\t-75.0\n", + "SSAccommodationMean:\t-50.0\n", + "AccommodationRateToSS:\t-0.143802128271498\n", + "AccommodationAtSSMean:\t-83.5991575049674\n", + "AccommodationRateMeanAtSS:\t166.006825685025\n", + "ISICV:\t2.95112315366106\n", + "ISIMedian:\t216.41\n", + "ISIBurstMeanChange:\t33.954571927781\n", + "SpikeRateStrongStim:\t10.0\n", + "AP1DelayMeanStrongStim:\t7.30999999999995\n", + "AP1DelaySDStrongStim:\t0.0\n", + "AP2DelayMeanStrongStim:\t33.8900000000001\n", + "AP2DelaySDStrongStim:\t0.0\n", + "Burst1ISIMeanStrongStim:\t28.135\n", + "Burst1ISISDStrongStim:\t0.0\n", + "RampFirstSpike:\t2046.34\n", + "FrequencyFilterType:\tLow-Pass\n", + "FrequencyPassAbove:\t29.0\n", + "FrequencyPassBelow:\t58.7316087498722\n", + "Ephyz_Cluster_ID:\t/3/1/4/\n", + "Channel_Type:\tNone\n", + "Time_Step:\tNone\n", + "Max_Stable_DT_Benchmark_RunTime_HH:\t911.1330720253954\n", + "Optimal_DT_Benchmark_RunTime_HH:\t466.46500114887556\n", + "CVODE_Benchmark_RunTime_HH:\t498.01998845545205\n", + "Stability_Range_Low_Corr:\t-1.875\n", + "Stability_Range_High_Corr:\t15.0\n" + ] + } + ], + "source": [ + "model_id = 'NMLCL000109'\n", + "\n", + "def get_model_details_from_neuromldb(model_id):\n", + "\n", + " url = 'https://neuroml-db.org/api/model?id=%s'%model_id\n", + " \n", + " with urllib.request.urlopen(url) as res:\n", + " model_details = json.load(res)\n", + " \n", + " for k in model_details['model']: print('%s:\\t%s'%(k,model_details['model'][k]))\n", + " \n", + " return model_details\n", + " \n", + "\n", + "model_details = get_model_details_from_neuromldb(model_id)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saved as NMLCL000109.nml.zip\n", + "It's valid!\n" + ] + } + ], + "source": [ + "def get_full_model_from_neuromldb(model_id):\n", + " \n", + " fname = '%s.nml.zip'%(model_id)\n", + "\n", + " url = 'https://neuroml-db.org/GetModelZip?modelID=%s&version=NeuroML'%model_id\n", + " r = requests.get(url)\n", + " with open(fname , 'wb') as f:\n", + " f.write(r.content)\n", + " \n", + "\n", + " import zipfile\n", + " with zipfile.ZipFile(fname, 'r') as z:\n", + " z.extractall('.')\n", + "\n", + " \n", + " print('Saved as %s'%fname)\n", + " \n", + "get_full_model_from_neuromldb(model_id)\n", + "\n", + "detailed_cell_file = model_details['model']['File_Name']\n", + "\n", + "validate_neuroml2(detailed_cell_file)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2) Generate 3D views of the cell" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6wAAAFsCAYAAADITDTZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB9sklEQVR4nO3dd3xTVf8H8E+69y4d0AJCy4YyyrJsy14CbVkyBR9FHIgPgvrgBBXFRwV9EBCQoQIyZCoie4+CyN6UtlCgdNKd8/vj/BIakrRpmyZp+3m/Xnkp957c+z1JmpvvPUshhBAgIiIiIiIisjBW5g6AiIiIiIiISBcmrERERERERGSRmLASERERERGRRWLCSkRERERERBaJCSsRERERERFZJCasREREREREZJGYsBIREREREZFFYsJKREREREREFokJKxEREREREVmkEiesCoUCCoWizCfu37+/+lj//POPwc/bsWMHxo4di9DQULi5ucHe3h4BAQGIjIzEl19+iXv37mmUv3XrFhYsWIBBgwahZs2asLe3h4uLC5o1a4YZM2ZolS9s69ateO+999CvXz8EBgaq4719+7be5yxdulRdrqiHlVXZ7hWojrN7926DysfGxmL27Nno1q0b/Pz8YGtrC09PT3To0AHz589HXl6ezuedO3cOr732Gjp27Ijg4GA4OTnB0dERdevWxfjx43HmzJky1QPQfM3s7OyQlJSkt2xOTg68vb3V5T/66CO9ZTMzM/H111+jZ8+eCAwMVL/39erVw8iRI7Fx40Yolcoyx1/Yt99+q47t+eefL7LsiRMnEBUVBT8/Pzg4OKB27dqYPHmy3vq/9957UCgUeO+994wasz4HDx7ESy+9hHbt2qF69epwcHCAs7MzGjZsiMmTJ+PGjRs6nzdmzBgoFAosXbq0xOdMSUnBpEmTULNmTdjZ2UGhUKBz584aZa5cuYIxY8agRo0asLe3R40aNTBmzBhcu3at5JUsRmZmJmbPno1WrVrBzc0Ntra28Pf3R9++ffHbb78Z7TymqFN6ejpmzJiBevXqwdHRET4+PujTpw/++uuvUh9z06ZN6NChA9zc3Er8nVSR8LrH6x6ve/rxusfrXmlU1Oteebtx4wYUCgVq1aqlta9WrVpQKBR6P4cVQanrIEoIgCjF0zQkJCQIa2tr9bFee+21Yp9z79498cwz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g4ODqFmzpujcubP45JNPxJUrVzTKz5s3T8TExIjQ0FDh4eEhbGxshKenp2jbtq2YOXOm3jgLf8mdPHlS9OvXT3h7ewt7e3vRqFEjMXfuXJ1r8Rma5Fy+fFmMGjVKBAYGCltbWxEYGChGjRqlFX9Z6y+EXONw2rRpomnTpsLZ2VnY2NgIX19f0aNHD/HLL78Ueb6SKG2dSiI1NVW89dZbIiQkRNjb2wsvLy/Rs2dPrdZNQxkjYRVCfqf37t1beHt7CxsbG/UP0sIJWGHmTFiF4HWP1z1e93ThdY/XvZKy1OteUQmrEELcu3dPvPPOO6JJkybC2dlZODo6iqeeekrExMToXAu5oKBArFq1SvTu3Vv4+fkJW1tb4e3tLRo3bizGjh0r1q9fr7FWKRNW3RRCPDHQgIiIiIiIiMgCmH7efyIiIiIiIiIDMGElIiIiIiIii1TqdVjJOPbv349FixYZXN7Ya4oZ2yeffIILFy4YVLZ+/fp46623yjmi4t2/fx9Tp041uPzzzz+vXpKDSGXq1Km4f/++QWUjIiLw/PPPl/gcixYtKnINxMJ8fHzw+eefl/gcROWN1z1e96hy4HWPTKZEI17J6FQDpQ19lHSQsqmpBmEb8tA3cYeplWRyDhQxAJ2qNkMnugEgRo8eXapzGDIhjuphyIRHRObA65758bpHxsDrHpkKJ10iIiIiIiIii8QxrERERERERGSRmLASmZgQAmlpaWDnBiIiIiKiojFhJTKx9PR0uLu7Iz093dyhEBERERFZNCasREREREREZJGYsBIREREREZFFYsJKREREREREFokJKxEREREREVkkJqxERERERERkkZiwEhERERERkUViwkpEREREREQWiQkrERERERERWSQmrERERERERGSRmLASERERERGRRWLCSkRERBbt5k0gMdHcURARkTkwYSUiIiKL5uQEXLhg7iiIiMgcmLASERGRRfPxAe7dM3cURERkDkxYiYiIyKIpFOaOgIiIzIUJKxEREVk8Jq1ERFUTE1YiIiKyeEKYOwIiIjIHJqxERERk8ezszB0BERGZAxNWIiIisnj5+eaOgIiIzIEJKxEREREREVkkJqxERERERERkkZiwEhERERERkUViwkpEREREREQWiQkrWZxjx47h5ZdfRqNGjeDs7Izg4GBER0fj0qVLWmXPnz+Pnj17wsXF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TFiJiKjSmDRpEqytrfH9998jLy9P3T24pK2rAFCtWjUAwIMHD4osp6+l05zdcVUx+/n5mS0GIiIiY2DCSkRElUZwcDAGDhyIhIQE/Oc//8HBgwcRGBiIQYMGlfhYLVq0AACcO3euyHKXL19Gfn6+1vZjx46V+JzG8ODBA9y5cwdOTk7lOmEUERGRKTBhJSKiSuXVV18FAHzyyScAgBdeeEHnWNDidOnSBQBw6NChIsslJyfjgw8+gBBCvS0uLg7Tpk1T/zszM7PE5y+tgwcPAgAiIiJga2trsvMSERGVByasRERUqXTo0AHNmzcHANja2mLixImlOs7TTz8NX19fHD9+HCkpKXrLBQYG4tNPP0WDBg0QFRWFbt26oUGDBnj48KF6UqVevXrhu+++K1UcJfXnn38CAAYOHGiS8xEREZUnJqxERFTpqJaDGTJkCPz9/Ut1DDs7O0yYMAE5OTn46aef9JYLCQnB9u3b4eXlhS1btuDEiRN45plnsHfvXsyZMweenp64cuWKekxsecrLy8OqVavg5uaG5557rtzPR0REVN4UonAfJiIiogquoKAAderUwc2bN3Hw4EG0a9eu1MeKj49HnTp10LhxYxw/flxj3+7du9GlSxd06tQJu3fvLmPUxvHrr79iyJAheP311zF37lxzh0NERFRmbGElIqJK5fvvv8fNmzfRrl27MiWrAFC9enW88cYbOHHiBDZv3mykCMuHUqnE+++/Dy8vL7zzzjvmDoeIiMgomLASEVGFd/HiRTz//PPo27cvJk+eDCsrK3z++edGOfaMGTNQo0YNvP3221AqlUY5ZnlYtWoVzpw5gw8//BBeXl7mDoeIiMgoSj5tIhERkYVJTEzE4sWLYWdnh0aNGuG9995D+/btjXJsZ2dnxMXFGeVY5WnkyJEYOXKkucMgIiIyKo5hJSIiIiIiIovELsFERERERERkkZiwEhERERERkUViwkpEREREREQWiQkrERERERERWSQmrERERERERGSRmLASERERERGRRWLCSkRERERERBaJCSsRERERERFZJCasREREREREZJH+Dy1jAWPG9NqvAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6wAAAHkCAYAAAA6r6JsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAACeN0lEQVR4nOzdeXxM1/sH8M9kj2wkIQuJLbYijb3Urnaq9qUEtfRHS1WV0qpaKlVbFW21WhRdUFpUtai1tqqlalfUFjsZQfbz++P5zkhkss/MnUk+79drXuTeO/c+d2aSO8895zxHp5RSICIiIiIiIrIxDloHQERERERERGQKE1YiIiIiIiKySUxYiYiIiIiIyCYxYSUiIiIiIiKbxISViIiIiIiIbBITViIiIiIiIrJJTFiJiIiIiIjIJjFhJSIiIiIiIpvEhJWIiIiIiIhsUo4TVp1OB51Ol+cDP//888Z9/fPPP9l+3qZNm9C/f3+UL18e3t7ecHV1RVBQEJo3b47Zs2fj5s2baba/ePEiFixYgE6dOqFkyZJwdXWFp6cnnn76aYwbNy7d9qlt2LAB7733Htq3b4/g4GBjvJcvX87wOYsXLzZul9nDwSFv9woM+9m2bVu2tj906BCioqLQrFkzBAQEwNnZGUWKFEGDBg0wf/58JCYmmnze8ePHMWLECDRs2BChoaEoVKgQ3N3dERYWhgEDBuDo0aN5Og8g7Wvm4uKCGzduZLhtfHw8/Pz8jNtPmTIlw20fPHiAjz/+GK1atUJwcLDxva9QoQJ69+6Nn376CSkpKXmOP7VPPvnEGNvAgQMz3favv/5C165dERAQADc3N5QuXRrDhg3L8Pzfe+896HQ6vPfee2aNOSO7d+/G0KFDUbduXRQvXhxubm7w8PDAU089hWHDhuHChQsmn9evXz/odDosXrw4x8e8d+8eXnnlFZQsWRIuLi7Q6XRo3Lhxmm3Onj2Lfv36oUSJEnB1dUWJEiXQr18/nDt3LucnmYUHDx4gKioKNWvWhLe3N5ydnREYGIh27dph7dq1ZjuONc7p/v37GDduHCpUqAB3d3f4+/ujbdu2+P3333O9z3Xr1qFBgwbw9vbO8d8ke8LrHq97vO5ljNc9Xvdyw16ve5Z24cIF6HQ6lCpVKt26UqVKQafTZfg5tAe5PgeVQwBULp6WxtWrV5Wjo6NxXyNGjMjyOTdv3lTPPfec8TmlSpVSzz//vOrZs6dq0qSJKlSokAKgPD091d69e43Pe/bZZxUA5eTkpGrVqqW6d++umjdvrry9vRUAVbRoUXXo0CGTx/Tx8TEeL/Xj0qVLGca5c+dO1bdv3wwfISEhCoBq2rRpjl+31AyxbN26NcttExMTjdt7enqqJk2aqB49eqj69esb34fatWuru3fvpnvuF198oQCogIAA1bBhQ9WtWzfVrl07VbJkSePr+s033+TpXBYtWpTm9Z0xY0aG23777bdptp08ebLJ7X799VdVtGhRY4x16tRR3bp1U506dVJPP/208fm1atXKU+yp/fvvv8rDw0PpdDoFQA0YMCDDbVeuXKmcnJyMMXTr1k2VKVPG+FqfOXMm3XMmTJigAKgJEyaYLebMvP322wqACg0NNX5mWrdurQICAhQA5eHhYfLz17dvXwVALVq0KMfH7Nq1q/H3u3v37qpv374qKirKuH7Xrl3G3/XKlSur7t27q8qVKxvj2bNnTx7OOK1bt26pp556yvh706JFC9WtWzdVvXp14+dn+PDheT6ONc7p+vXrqnz58gqACgoKUl27dlUNGzZUOp1O6XQ69fHHH+d4n4cOHVLOzs7K0dFRNW/eXEVGRqq+ffuqEydO5DleW8PrHq97vO6Zxuue4HUvZ+z1umcN58+fVwBUyZIl060z/A06f/681eMyl9yegyYJa1RUlAKgihcvrgAof39/FR8fn+H29+7dUxUqVFAAVMWKFdWOHTvSbRMXF6cWLFigAgMD1Zo1a4zLu3XrpmbPnq1u3bqVZvsbN26oxo0bKwCqXLlyKikpKd0++/fvr6ZOnao2btyobty4ka0Ld2YePXqkihQpogCo5cuX52ofBjm9cNeoUUOtWLFCxcXFpVn3999/q6CgIAVA9e/fP91zz58/b/ILaHJyspo+fboCoAoVKqTu3LmT63MxXLjDw8OVs7Ozqly5cobbNm/e3Hixy+jCvX79euMXkpdeekldv3493Tb//fefevnll1WRIkVyHXdqycnJqkGDBsrT09N44crown3lyhXjH+oFCxYYlyclJanevXsbzy8lJSXN86x94T5+/LjJPyjx8fHqtddeUwBUiRIl0v3u5PbCnZCQoJycnJSbm5uKiYlJt/7BgwcqODhYAVBjx45Ns27s2LEKgAoJCVEPHz7M0XEz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lOxcuJVS6sCBA6pTp06qaNGiysXFRZUsWVK98sor6e7cPrnfCRMmqHPnzqmePXuqgIAA5eLiosLCwtS7776rHjx4kOHxzp8/r15//XVVpUoV5eHhodzc3FTJkiVV48aN1QcffKDOnj2bZvt58+ap7t27q/Lly6vChQsrJycnVaRIEfXMM8+oCRMmZBhn6j9yBw8eVO3bt1d+fn7K1dVVVa5cWc2aNcvkXHzZTXLOnDmjIiMjVXBwsHJ2dlbBwcEqMjIyXfx5PX+lZI7DMWPGqPDwcOXh4aGcnJxU0aJFVcuWLdX333+f6fFyIrfnlBMxMTHqrbfeUuXKlVOurq7K19dXtWrVKl3rZnaZI2FVSv6mt2nTRvn5+SknJyfjF9LUCVhqWiasSvG6x+ser3um8LrH615O2ep1L7OEVSmlbt68qd555x1VtWpV5eHhodzd3VWZMmVU9+7dTc6FnJycrL755hvVpk0bFRAQoJydnZWfn5+qUqWK6t+/v1qzZk2auUqZsJqmU+qJgQZERERERERENsD6df+JiIiIiIiIsoEJKxEREREREdmkXM/DSuaxa9cuLFy4MNvbm3tOMXP74IMPcPLkyWxtW7FiRbz11lsWjihrt27dwqhRo7K9/cCBA41TchAZjBo1Crdu3crWtvXr18fAgQNzfIyFCxdmOgdiav7+/pgxY0aOj0Fkabzu8bpH+QOve2Q1ORrxSmZnGCid3UdOBylbm2EQdnYeGRXusLacFOdAJgPQqWDLbqEbAKpv3765OkZ2CuIYHtkpeESkBV73tMfrHpkDr3tkLSy6RERERERERDaJY1iJiIiIiIjIJjFhJSKTlFLQ6/VgJwwiIiIi0goTViIy6f79+/Dx8cH9+/e1DoWIiIiICigmrERERERERGSTmLASERERERGRTWLCSkRERERERDaJCSsRERERERHZJCasREREREREZJOYsBIREREREZFNYsJKRERERERENokJKxEREREREdkkJqxERERERERkk5iwEhERERERkU1iwkpEREREREQ2iQkrERERERER2SQmrERERERERGSTmLASERERERGRTWLCSkRERERERDaJCSsREdm9vXu1joCIiIgsgQkrERHZvU2bAKW0joKIiIjMjQkrERHZPR8fICZG6yiIiIjI3JiwEhGR3StaFLhxQ+soiIiIyNyYsBIRkd0rVgy4eVPrKIiIiMjcmLASEZHdK1aMLaxERET5ERNWIiKye+wSTERElD8xYSUiIrvn7w/cuqV1FERERGRuTFiJiMjuOTkByclaR0FERETmxoSViIjyBS8vrSMgIiIic2PCSkRE+cL9+1pHQERERObGhJWIiIiIiIhsEhNWIiLKF5TSOgIiIiIyNyasRESULzg5AYmJWkdBRERE5sSElYiI8oVixYCbN7WOgoiIiMyJCSsREeULAQHA9etaR0FERETmxISViIjyBSasRERE+Q8TViIiyheYsBIREeU/TFiJiChfCA4GbtzQOgoiIiIyJyasRESUL7i4ALGxWkdBRERE5sSElYiI8o0iRYA7d7SOgoiIiMyFCStRLvz555949dVXUblyZXh4eCA0NBTdunXD6dOn02174sQJtGrVCp6envD19UWfPn1w08TcGykpKfjwww9RunRpuLm5ITw8HN9++601Toco32jaFPj9d62jICIiInNhwkqUC9OmTcMPP/yAZs2aYc6cORg8eDB27NiB6tWr459//jFud/nyZTRs2BBnz57F1KlTMWrUKPz8889o3rw5EhIS0uzz7bffxpgxY9C8eXPMnTsXoaGh6NWrF7777jtrnx6R3apSBTh6VOsoiIiIyFx0SimldRBE9mb37t2oWbMmXFxcjMvOnDmDqlWrokuXLli2bBkAYOjQoVi8eDFOnjyJ0NBQAMDmzZvRvHlzLFiwAIMHDwYAXLlyBaVLl8bgwYMxb948AIBSCo0aNcL58+dx4cIFODo6WvUc9Xo9fHx8EBMTA29vb6semygv3n0XmDRJ6yiIiIjIHNjCSpQL9erVS5OsAkC5cuVQuXJlnDhxwrjshx9+QLt27YzJKgA899xzKF++PFasWGFc9tNPPyExMRFDhw41LtPpdBgyZAguX76MPXv2WPBsiPKXMmWAf//VOgoiIiIyByasRGailML169fh7+8PQFpNb9y4gZo1a6bbtnbt2jh06JDx50OHDsHDwwOVKlVKt51hPRFlT/PmwKZNWkdBRERE5uCkdQBE+cXy5ctx5coVTPpfX8To6GgAQFBQULptg4KCcOfOHcTHx8PV1RXR0dEICAiATqdLtx0AXL16NdNjx8fHIz4+3hynYaTX6826PyJrKV4cuHdP6yiIiIjIHJiwEpnByZMn8corr6Bu3bro27cv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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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cv/99xtJplu3bub48eNO+z7//HPHH16VqVir6p6uvvpqI8kMGjTInDlzxrH9888/N/7+/sbPz89s2bKlXOe0vx+nT59eqdhqAuo96j1jqPeKot47j3qv7GpyvVcVSFhd80rCGh8fbySZf//7345v1+bNm1di+Ztvvtnx7VPRX6CiDh06ZHbu3FmmOA4cOOC4nxUrVlywfGUr7vfff99IMrVr1zZZWVkVOkfRWMpScV/IO++8YySZ0NBQk5ubW65j7T+/Tz/9tMLXt1fcgwYNMtddd52R5NRaYPfrr78aPz8/k5iY6Kgcilbcx44dM7Vr1y7zt4DfffddheMu7KWXXjKSzKuvvuqoYEuquB966CEjyQwePLjYvtOnTztaOL788kunfVVdcZcmNzfXhISEGEnmhx9+cNpX0Yr7119/LfFD2hhjXn31VSPJtG7d2uTn5zvty8/Pd3yT+ve//71c1y1Jx44dS/1ssv8R+dJLL1X4GlVxT9u2bTOSjL+/v9m3b1+x/bfffruRZMaPH1+u806aNKnCLQo1DfUe9V5h1HsW6r3zqPfKribXe1WBhNW1Sg0o+cc//qFu3bopPDxctWvX1ogRI/T999+Xesx3332n3bt3q27durr22ms1adIkSdJbb73lsvyePXv0/vvvS5JeeuklRUdHl3r+hg0bqk2bNmWKv3HjxqpXr54k6cCBA2U6pjL++c9/SpJuuukmhYSEePx6ZdWlSxdJUlZWlo4dO1auYwMCAiRJwcHBbonltttuk3T+tSpszpw5KigocJRxZdasWTp16pQaNGigP//5zxe8Xt++fSse7P/89NNPeuSRR9SvXz/dddddFyz/0UcfSZJuvPHGYvsiIiI0evRoSdKHH35Y4jl+/fVX3XLLLYqNjVVISIhat26tJ554QllZWSUes2vXLv3mN7/RJZdcopCQEEVFRalv37569913LxhzUYXHo5X2s9+yZYuuu+461a9fX6GhoercubNeeeUV5efnFztfs2bNHPdWeNybfbya/XUbP358sbFwfn5+GjdunKSSX7fy3n9Zf0ftnyEVUdl7Ks81Lr/8csdrXJj9ffjZZ5+VOKavMPuYsjlz5kiSJk2a5PhZ2cddFR6Dk5+fr5deekldunRRREREsbGgX331lUaOHKkGDRooKChIcXFxGjdunDZs2ODy+v3793e8L77//ntdddVVqlu3rmrVqqV+/fppxYoVjrJffvmlBg0apDp16igiIkJDhgzRpk2bLvyilYJ6r3yo9y6Meo96j3rPUl3rvcJOnjypJ598Ut27d1dUVJRCQ0PVsmVLjR07Vl988UWx8nl5eXrzzTfVv39/RUdHKzg4WC1atNBdd91VJZ/BhevMzZs367rrrlO9evUUHBys9u3b68UXX5Qxpthxhcdl//TTTxo3bpwaNGig8PBw9ejRQ5988omj7Nq1azV69GjHe75Xr15asmSJe2+kvJmx/vcN5+9+9ztjs9lMnz59zA033OD4ViYgIMB8+OGHJR5v/9bY/i3ggQMHjJ+fn/Hz8zP79+8vVv6VV15xfDvrqvtSZRw9etTRhaYs39ja770i3zTbvyWVZDZt2lSBaF3H4o5vmj/66CMjyQQFBRXrOlWa2bNnG0mmQYMGLruylFXhb5rz8vJMXFyciYyMdOoOUlBQYJo1a2bCwsJMenp6id80d+nSxUgy9913X4XjKY+8vDyTmJhowsLCzM8//2yMMaV+05yRkeH42RX9htbO/p4vOs7Ift5bbrnF1K1b1zRs2NAkJSWZkSNHmvDwcCPJXH755S5bMebNm+f4Zrht27bm2muvNQMHDnQc56pbXGn3/OijjxpJpn379sW+IbX/bO666y4TEhLiGJczdOhQExQUZCSZMWPGOHX9uvXWW831119vJGv8SuHxb/aueXXr1i21VeOTTz4xkjU+zx33/9hjj12wa1RMTIw5depUmV+7oipzT2Vlf12nTJnicn96errjPblt27YLnu+jjz4yt956q7nkkksc7zn7z8o+7sr+DXHTpk3N6NGjTVBQkBk0aJC54YYbTOfOnR3nsr+PbDabufzyy80NN9xgEhISHN+Mv/XWW8Wu369fPyPJPPjggyYgIMB06dLFjBs3znFccHCwWbVqlZk1a5bx8/MzvXv3NmPHjnV8ax8REeFyrFxpqPeo9+yo96j3qPcuvnrPbvPmzY5hHVFRUWbEiBFm3LhxplevXiY0NNT069fPqXxGRoZjGEZERITp16+fGTNmjGO4R926dYt9Nrq7hdVeZ/7hD38wQUFBpl27dmb8+PGmX79+jrrgt7/9bbHj7O/p++67z4SHh5s2bdqY8ePHm169ejnq7fnz55uPPvrIBAYGOupi+3j5gIAAl714qrxLcGhoqFmyZInTvj//+c+OH6Kr8ROnTp0yoaGhRpLZvHmzY/uVV15pJJknn3yy2DH2ir6ykzW4MnXqVCNZg7FLG0tkV5mK+4knnjCSTJcuXSoSaomxVLbiLigocLz5rrvuuhLLnTlzxvFBes0115hWrVoZyZoowdXYqvIoXHEbc34Mw7/+9S9HmcWLFzsqLWOMy4r73Llzjj+OCh/rSfZxaX/5y18c20qruH/44QfHz66kD/wPP/zQSNYYt8Ls55Vkrr76aqc/bA4cOOD4g/wPf/hDsWsGBwebkJAQ89///tdp3759+0ynTp2MJPP222+7jOfXX391/OxHjRplGjdubCSZVq1amR9//LFYefvPRpK5++67zblz5xz7fvzxR8ekIEW7+5T2IV34D57Cnx2Fbdq0yVEmMzOz0vefmZnp+GyKiIgwV155pRk3bpzp1q2b44+ksnbDdKUy91Qe9skyXn755RLL2CfjWbhwYZnPW1oXOPvPUrLGe/3000/FynzxxRdGkgkJCTFff/21074333zTSDKBgYHF3mP2ytdms5l33nnHad+UKVOMJNOmTRsTERFhvvnmG8e+vLw8xx8xd9xxR5nv0xjqPeo96r3CqPeo9yqqJtd7mZmZjgnkbrnlFnP69Gmn/adOnTKLFy922nbjjTcaSWbkyJHF6oe//OUvRio+n4CnElZX778lS5YYm81m/P39i33GF35PP/30005ftvz1r3911O916tQp9tnzwAMPGMn1EIAqT1hLmuGwe/fuRpJ55plniu17/fXXjWR9c1PYvHnzjCTTokWLYgPuhw0bZiT39zNfvHix45uFss72V9GKu6CgwDRv3txIMrNmzapIuCXGUtmK214ZREREmF27dpVY7uTJk45r2h8tW7Z0yzfdRSvuXbt2GUmmf//+jjLjx483ksyyZcuMMa4r7kOHDjliKzoOxhO2bt1qgoKCTO/evZ2+bS2t4l61apUjxsIVWmFff/21kaxv/guznzc0NNSkpaUVO+6zzz4zkkxkZKTTt83jxo0zUsmzUK5bt87l76VdcnJysZ99165dS6xs7D+b2NhYl996/+1vf3N8SBdW2od0amqq49oltY7Z3zeSzMGDB91y/7m5uebBBx90zIBpf9StW9c8/vjjxSqs8qjMPZWHfezkP/7xjxLL2CfAKM/Mp2VNWEv6I3rQoEFGKvkb8JEjRxpJ5s4773Tabq98k5KSih1z/Phxx3UfeuihYvs3btzoqGvKg3qPeo96z0K9R713sdZ7L7/8spFkEhISytTzZfv27cZms5m4uDiTkZHhssyIESOMJPPZZ585tnkqYS3pyzl7fVO0rra/p3v27Fmsjjp37pyJjo4usS4+duyY4/e56BwBVT6G9dZbb3W5/ZZbbpEkl+ukvfnmm5JUbCzG1Vdfrbp162rv3r1VsjbS1q1blZSUpPz8fN1333264YYbPHq9JUuWaN++fQoJCXE5fsNb/vWvf+nJJ5+Un5+f/vnPfyo+Pr7EsrVr15axvuDQoUOHtGjRItWvX18DBgzQQw895Na44uPjdcUVV+i7777Tnj17dPLkSX388ce65JJL3DL2xh3y8vJ06623Ol67yq4vWB5Dhw5VTExMse0jR45U3bp1lZGR4RinV1BQ4BhTYR8XUlT37t0VERGh5ORkZWdnF9ufkJAgY4wKCgqUkpKiefPm6ezZs+rWrZv++te/lhjn2LFjXY6HsX927N69WwcPHrzwDVdCZe4/LS1Nl19+uf72t7/p6aef1p49e5SZmal169apW7dumjFjhvr06aPTp0979B5quuuvv77Ytry8PK1atUqSNU7Gldtvv12StHTpUpf7R4wYUWxbdHS06tatW+J++2dcRd931HtlR71XPtR7paPeKzvqPc/48ssvJVl1k7+//wXLL1q0SMYYDR8+XLVq1XJZxj7vw+rVq90WZ0lGjRrlcnu7du0kSampqS73Dx8+vNjcEwEBAWrRooUk13Vt3bp1FR0drdzcXB0/frwyYTtU+NPGHmhJ24suMr5lyxZt3LjRZeUVFBSkm266SVLxSQfq168vSaUuql0eO3fu1ODBg3Xq1ClNmjRJr7zyilvOWxr7PV177bWqU6eOx69XFvPnz3f8AfWPf/xDSUlJZT62YcOGGj58uJYvX66EhAS98MILWrhwoVvju+2222SM0Zw5c/T+++8rOzvbMblLSerWreuoQN31finJM888o02bNmnGjBllnuxEktOH1pkzZ1yWyczMlCRFRka63F/S754kx0LT9t+/48ePKyMjQ5LUpEkTp0kd7A8/Pz9lZmaqoKCg1A8Wm82mRo0aKSkpSWvWrFHDhg31u9/9Tlu2bClXnLVq1XIkFUU/J0pSntdNOv/aVeb+b731Vq1fv15PPfWUpk+frhYtWjgmG1i4cKE6deqkLVu26IUXXijTPbjrnip6nZKuUfg6Fb1GSRo0aKCwsLBi248fP+74I6mk98kll1wiqeRKtGnTpi63R0RElLjf/lrk5ORcIHLXqPfKjnqv/Kj3qPeKHmNHvVex67iz3vv1118lSW3bti1T+T179kiyJtdz9TOw2Wx6+OGHJUlHjx4t0zkro6Q6037/rr64Ke240upa6fzPoKTzlleAW87igiky45R9NsSAgACNHDmyWHn7L8yHH36oU6dOqXbt2pKkbt266Z133tGmTZuUn59fpm81SrJr1y4NHDhQR44c0S233KI333yz1IrAHU6dOuWYrczeYuBtH374oW688UYVFBRo9uzZpc4+WBr7H1ybN2/WRx995PLnWlFJSUm6//779fbbbzsq5JJaN+wCAgLUuXNnbd68WevXr9fNN9/stniKsv9MP/vsMy1atMhp3759+yRJn3/+uePbM3vLS+HZ6vbv369OnToVO7d91jh7JVwR9t+/goICx7YLvX5S2We9rF27tq699lq9+uqr+vTTT3XppZdWKs4LqVWrlqKjo3XixAnt37/f5fXsr1u9evUUHh4uqeL3n5qaqsWLF0uSy5aowMBAjRkzRlu3btU333yjGTNmlOk+3HFP5dW8eXNt2rRJ+/fvd7k/IyPD8cdNZd5zroSGhrr1fIVdqHWnKlt/7Kj3LNR7FUO9R71XGPVezaz37Ow/h4SEhAu+VxITEz0SQ2EVrROrS11b4YR17969SkhIKLbd/qHVuHFjx7acnBy99957kqxvNOxdwVzJzs7We++9p3vuuUeS1d1jypQpOnXqlD799FNde+21FYp39+7dGjBggNLS0jRhwgTNmTOnSl5k+7ekLVq00MCBAz1+vQv5+OOPNX78eOXn5+v111/XnXfeWanz2T9M3P3Nbnh4uMaOHau33npLBw4c0LBhw5zeUyW5+uqrtXnzZv3nP//R888/77ZlB0qycuXKEvcdOnRIhw4dctoWGRmpVq1a6eeff9aGDRtcVtz25Ty6du3q8rx79+4t8ZpFf//q1aun0NBQZWVl6YUXXqjUVPRFXehnX1Kcp0+fdvyhXpafqV3Xrl31zTffaMOGDS67trh63Sp6/4UruZK+fY2KipIknThxosz3UFRF7qki1/jwww9LXCbGvj08PFyt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d87bkTgbPFhascLbUQAA4FtIWAH4PGOMDh8+rHr16kmyWk2PHDmi7t27Fyvbs2dPJScnO54nJycrPDxc7dq1K1bOvh9VKyxM6tFD2rDB25E48/e3JoU6edLbkQAA4DsCvB0AAHjae++9p9TUVD355JOSpLS0NElSbGxssbKxsbE6ceKEcnJyFBwcrLS0NDVs2FA2m61YOUk6ePBgidfNyclRTk6Ou25DktUl+GIXEGBNulTdWlglqWdP6euvpSuv9HYkAAD4BhJWAD5t586duueee9SrVy/deuutkqSsrCxJUrCLwYYhISGOMsHBwY5/SytXkpkzZ2rGjBmVvgc4a95c+uEHKTbWas2sU8fbEZ1ns0mNGkkpKVLjxt6OBgCAmo+EFYDPOnTokK666ipFRUVpwYIFjsmRQkNDJcll62f2/xbUtJcJDQ0tUzlXpk2bpilTplTuJorIyMhQkyZN3HrOmsZmkwoKpPh4aeNGqVs3b0fkrGNHayZjElYAACqPhBWAT0pPT9fw4cN16tQprVixQnFxcY599u689q7BhaWlpSk6OtrRqhobG6ulS5fKGOPULdh+bOHzFhUcHOyydRaVZ7NJxljdgo2xnlcngYFWbIGB3o4EAICajUmXAPic7OxsjRo1Srt27dLChQvVvn17p/2NGjVS/fr1tcHFrD3r1q1TQkKC43lCQoLOnj3rNMOwJK1du9axH1WvZUvpp5+ktm2r3+RLknTZZdL333s7CgAAaj4SVgA+JT8/X+PGjdOaNWs0f/589erVy2W566+/XgsXLtSBAwcc25YsWaJdu3YpKSnJse3qq69WYGCgXnvtNcc2Y4z+/ve/q1GjRurdu7fnbgYlioyUDh6Uate2JmCqbkJCpNxcb0cBAEDNR5dgAD7l97//vT799FONGjVKJ06c0Lvvvuu0f8KECZKk6dOna/78+RowYIB++9vfKjMzU88//7w6deqkSZMmOco3btxYDzzwgJ5//nmdO3dOPXr00Mcff6wVK1bovffec4yLhfc0by79+qvUrJm3I3EWHi6dPWstwwMAACrGZowx3g4CANylf//++u6770rcX/gjb9u2bZoyZYpWrlypoKAgXXXVVXrxxRfVsGFDp2MKCgr03HPPafbs2UpLS1N8fLymTZumm266yWP3UZKMjAxFRUUpPT1dkZGRVX796iQ5WerU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VgAAfAXrsAKokMDAQPXv31/9yzNjDeBFyclSYKDUqVP5jlu71lo2pjzOnStfeQAA4BqTLgEAfFpBgdU1NiJC6tixfMcaYx1fp075jjtzpnzlAQCAa7SwAgB81sGD0qZN0uDBUkhI+Y83RurZs/zHVeRaAACgOBJWAIDPMUZas0YKCqrc5Ed+ftajvFhSBgAA9yBhBQD4lF9/lbZvly6/3FqX1Btyc71zXQAAfA0JKwDAJxgjffONFBdXvhl93Y3WVQAA3IeEFQDgE2w2a6yqi2WBq1R6urVmKwAAqDxmCQYA+AxvJ6uSdOqUFBPj7SgAAPANJKwAALjR0aNS48bejgIAAN9AwgqgQr788ktvhwBUS4cPSw0bejsKAAB8AwkrgAoZMWKE2rRpo1deeUUZGRneDgeoNvLypABmiAAAwC1IWAFUSLt27bR7925NmTJFjRo10l133aUff/zR22EBXpeV5e0IAADwHSSsACpk27Zt+vbbb3XttdcqJydHs2fP1qWXXqoBAwbov//9rwpY2wMXKVpXAQBwHxJWABXWv39/LViwQHv37tUjjzyiBg0a6LvvvtPYsWPVrFkzPfPMMzpy5EiVxrRkyRLddtttat26tcLCwtSyZUvdcccdSktLc1l+9erV6tOnj8LCwhQTE6P7779fmZmZxcrl5ORo6tSpiouLU2hoqBITE7V48WJP3w5qoKAgb0cAAIDvsBljjLeDAOAbzp07pwULFmjWrFlas2aNbDabAgMDlZSUpHvvvVeJiYkej6F79+46ceKEkpKSFB8frz179mjWrFkKCwvT5s2bFVNovZHNmzerV69eateunSZPnqyUlBS98MILGjBggL744gun895www1asGCBHnjgAcXHx2vu3Llav369li5dqj59+nj8vuwyMjIUFRWl9PR0RUZGVtl1UTa5udKiRdI113g7EgAAfAMJKwC3y8vL0x//+Ec9++yzjm02m029e/fWCy+84NHEdfny5erTp4/8/PyctvXr10+PPPKInn76acf2ESNGaPPmzdq5c6cj+XvzzTd155136quvvtLQoUMlSevWrVNiYqKef/55Pfjgg5Kk7OxsdezYUQ0aNNDq1as9dj9FkbBWb/v3S4cOST17ejsSAAB8A12CAbjN4cOH9dRTT6lFixZ67rnnJEldunTR1KlT1aRJE61atUp9+vTR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1IEJAADv+F+e5pNatWqlq6++WkuXLlV+fr4kKTQ0VDku1vHJzs527He3pk2bOj2PiopSSEiI6tWrV2z7yZMn3X59AIB3kLACAFBBublSkdVefFKTJk2Um5urM2fOSLK6/qalpRUrZ98WV8Epk00pawP5+/uXaduFzgMAqFlIWAEAqKAdO6ROnbwdheft2bNHISEhioiIkCQlJCRo165dysjIcCq3du1ax/4LOX36dLFthw8frnywAACfQsIKAEAFFRRIJTTy1UhHjx4ttm3Lli369NNPNXToUPn9byrkMWPGKD8/X2+88YajXE5OjubMmaPExEQ1adLkgtc6ceKEtmzZ4nT8okWLJNFCCgA4j0mXAACAJGvpmNDQUPXu3VsNGjTQ9u3b9cYbbygsLEzPPvuso1xiYqKSkpI0bdo0HTlyRK1atdLbb7+tffv26a233irTtYKDgzVq1Cjde++9CgkJ0bvvvutosX3qqad01113qb6vTL8MAKgwWlgBAKiAs2clD8wt5FXXXHONjh07ppdeekl33323/vOf/+i6667Thg0b1K5dO6ey//rXv/TAAw/onXfe0f33369z585p4cKFZV5OJiYmRtOnT9fLL7+sP/zhD2rWrJlWrFihJk2a6J///KcKCgo8cYsAgBrGZuh3A8CHzJ07V5MmTXK5Ly0tTTExMU7bPv30Uz3xxBPavn27GjRooEmTJumxxx5TQIBzB5RTp07p4Ycf1kcffaSzZ8+qZ8+eevHFF9W1a1eP3YsrGRkZioqKUnp6uiIjI6v02nC2fbvUurUUQF+lcps4caKWLVumffv2eTsUAEA1RzULwCc9+eSTatGihdO22rVrOz3/4osvdM0116h///7629/+pq1bt+rpp5/WkSNH9PrrrzvKFRQU6KqrrtKWLVv00EMPqV69enrttdfUv39/bdy4UfHx8VVxS6hmAgJIVgEA8DSqWgA+afjw4erevXupZR588EF17txZX3/9taNFNTIyUn/605/029/+Vm3btpUkLViwQKtXr9b8+fM1ZswYSdLYsWPVunVrPf7443r//fc9ezOols6e9XYEAAD4PsawAvBZp0+fVn5+vst927dv1/bt2zV58mSn7r933323jDFasGCBY9uCBQvUsGFDXXfddY5t9evX19ixY/XJJ58oJyfHczeBastm83YEAAD4PhJW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r169XJa7/vrrtXDhQqclgpYsWaJdu3Y5vVevvvpqBQYG6rXXXnNsM8bo73//uxo1aqTevXt77mYAAB5hM8YYbwcBAHCPa665Rp988oluu+02DRgwwGlfRESErrnmGsfzTZs2qXfv3mrfvr0mT56slJQUvfjii+rbt6+++uorp2PHjh2rjz76SL/73e/UqlUrvf3221q3bp2WLFmivn37VsWtVWu8PhXzwAMP6JVXXtGoUaOcWvXtJkyYIMnq4t6lSxfVrl1bv/3tb5WZmannn39ejRs31vr1650mWnr44Yf1/PPPa/LkyerRo4c+/vhjff7553rvvfd04403Vtm9AQDcg4QVAHxI8+bN9euvv7rc16xZM+3bt89p28qVKzV16lRt2rRJtWrV0tixYzVz5sxiY16zs7P12GOP6d1339XJkyfVuXNnPfXUU7ryyis9dSs1Cq9PxfTv31/fffddifsL/4mybds2TZkyRStXrlRQUJCuuuoqvfjii2rYsKHTMQUFBXruuec0e/ZspaWlKT4+XtOmTdNNN93ksfsAAHgOCSsAAAAAoFpiDCsAAAAAoFoiYQUAAAAAVEskrAAAAACAaomEFQAAAABQLZGwAgAAAACqJRJWAAAAAEC1RMIKAAAAAKiWSFgBAAAAANUSCSsAAAAAoFoiYQUAoBRnzpxRkyZNdOmll6qgoMDb4ZTo3Xfflc1m02uvvebtUAAAcBubMcZ4OwgAAKqrRx55RH/605+0cOFCXXXVVd4Op0QFBQVKSEhQamqqdu/erejoaG+HBABApdHCCgBACVJTU/Xiiy+qR48e1TpZlSQ/Pz89/vjjOnHihJ5++mlvhwMAgFuQsAIAUILXXntNOTk5uv32270dSpmMHj1a9evX11tvvaXMzExvhwMAQKWRsAIAarz77rtPNptNV1xxhfLy8ortf+SRR2Sz2dS1a1dlZ2eX6Zy5ubn6xz/+oeDgYI0fP77Y/mXLlslms6l///4lnsNms8lms5W6/d1331XPnj0VERGh+vXr64YbbtD+/fslScYYzZo1SwkJCQoPD1e9evU0ceJEHTlyxOX1AgMDdeONNyojI0PvvPNOme4TAIDqjIQVAFDjvfjii+revbtWrlypRx991Gnfl19+qZkzZyoyMlLz5s1TSEhImc65atUqHT16VD169FBUVJQnwta0adM0adIk1apVS8OHD1dYWJj+/e9/q0+fPjp58qTGjx+vhx56SLGxsbryyivl7++vt99+W0OGDFFubq7Lcw4ZMkSS9PHHH3skZgAAqlKAtwMAAKCygoKCNG/ePHXt2lV//vOf1a9fPw0fPlwpKSm6+eabZYzRm2++qVatWpX5nN9++60kqVevXp4KW//4xz+0YcMGXXrppZKkrKwsDR06VCtXrlS/fv109uxZ7dy5U82aNZMkHTt2TL169dIPP/yg+fPn66abbip2zl69eslms2nlypXKzc1VUFCQx+IHAMDTaGEFAPiEFi1aaO7cuTLG6Oabb9bevXs1fvx4HTt2TPfee6+SkpLKdb7k5GRJUrt27TwRriTpySefdCSrkhQaGqopU6ZIkrZu3aq//vWvjmRVkurVq6e77rpLkrRkyRKX54yOjlZMTIwj2QUAoCYjYQUA+Iyrr75aU6ZM0fHjx9WlSxetWrVK3bt314svvljucx0+fFiSVLduXXeH6TBixIhi2+Lj4yVJAQEBGjp0aIn7Dx48WOJ57THb7wEAgJqKhBUA4FOee+45tW/fXunp6QoPD9e8efMq1C02PT1dkhQZGenuEB2aNm1abFtERIQkKTY2VgEBxUfu1KpVS5JKnTzKHvPJkyfdESYAAF5DwgoA8Clr167Vrl27JElnzpzR1q1bK3Se2rVrS5IyMjLcFVoxfn4lV8Ol7bsQe7Jdp06dCp8DAIDqgIQVAOAzjh07pvHjxysvL0+TJk2SzWbTxIkT9euvv5b7XA0aNJAkHT9+vNRyJbV0erM7rj3mhg0bei0GAADcgYQVAOAT7JMtpaSk6JZbbtE///lP/f73v9fJkyc1btw4nTt3rlzn69q1qyRp+/btpZbbvXu3y7Vf169fX67rucvx48d16NAhhYWFeXTCKAAAqgIJKwDAJ8ycOVNffvml2rdvr9dee82xrVevXlq7dq0efvjhcp1vwIABkqQ1a9aUWu7EiRN68sknZYxxbDtw4ICmTp3qeH7mzJlyXbsyVq9eLUnq06ePAgMDq+y6AAB4AgkrAKDGW758uf74xz8qLCxM8+fPV3h4uCRrpt1///vfio6O1ssvv6xPPvmkzOe8/PLLVb9+fW3YsEGnTp0qsVxcXJyee+45tWvXTklJSRo0aJDatWunkydPOiZVGj58uF5//fVK3WNZffPNN5Kka665pkquBwCAJ5GwAgBqtKNHj+qGG25Qfn6+Xn31VbVv395pf9OmTTV37lzZbDZNmjRJ+/btK9N5g4KCdOeddyonJ0cffPBBieXi4+P15ZdfKjo6Wp9//rk2btyowYMHa/ny5Xr++edVp04d/fzzz44xsZ507tw5vf/++4qMjNTNN9/s8esBAOBpNlO4DxMAAHBITU3VJZdcoo4dO2rDhg1O+5YtW6YBAwaoX79+WrZsmXcCLOK///2vxowZo9/97nd66aWXvB0OAACVRgsrAAAlaNSokX7/+99r48aNWrhwobfDKVVBQYFmzJih6OhoPfroo94OBwAAtyBhBQCgFNOnT1fjxo31yCOPqKCgwNvhlOj999/X1q1b9dRTTyk6Otrb4QAA4BYB3g4AAIDqLDw8XAcOHPB2GBc0YcIETZgwwdthAADgVoxhBQAAAABUS3QJBgAAAABUSySsAAAAAIBqiYQVAAAAAFAtkbACAAAAAKolElYAAAAAQLVEwgoAAAAAqJZIWAEAAAAA1RIJKwAAAACgWvp/K34NJr2KDNIAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "from pyneuroml.plot.PlotMorphology import plot_2D\n", + "\n", + "planes = ['yz', 'xz', 'xy']\n", + "for plane in planes:\n", + "\n", + " plot_2D(detailed_cell_file,\n", + " plane2d = plane,\n", + " min_width = 0,\n", + " verbose= False,\n", + " nogui = True,\n", + " square=False)\n", + "\n", + "detailed_cell_doc = pynml.read_neuroml2_file(detailed_cell_file)\n", + "detailed_cell = detailed_cell_doc.cells[0]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3) Analyse cell spiking behaviour" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Tst.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Nap_Et2.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTs2_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ih.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/pas.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Im.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca_LVAst.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SK_E2.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Pst.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/CaDynamics_E2_NML2.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca.channel.nml\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" -validate iv_bAC217_L23_MC_40be3bf0e8_0_0.net.nml ) in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/iv_bAC217_L23_MC_40be3bf0e8_0_0.net.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Tst.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SKv3_1.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Nap_Et2.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTs2_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ih.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/pas.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Im.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NaTa_t.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca_LVAst.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SK_E2.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/K_Pst.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/CaDynamics_E2_NML2.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/Ca.channel.nml\n", + "pyNeuroML >>> INFO - Loading LEMS file: LEMS_iv_bAC217_L23_MC_40be3bf0e8_0_0.xml and running with jNeuroML_NEURON\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -Djava.awt.headless=true -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" LEMS_iv_bAC217_L23_MC_40be3bf0e8_0_0.xml -neuron -run -compile -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/fromnumeric.py:3432: RuntimeWarning: Mean of empty slice.\n", + " return _methods._mean(a, axis=axis, dtype=dtype,\n", + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/numpy/core/_methods.py:190: RuntimeWarning: invalid value encountered in double_scalars\n", + " ret = ret.dtype.type(ret / rcount)\n", + "pyNeuroML >>> INFO - Generating plot: Membrane potential traces for: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n", + "pyNeuroML >>> INFO - Generating plot: Firing frequency versus injected current for: bAC217_L23_MC_40be3bf0e8_0_0.cell.nml\n" + ] + }, + { + "data": { + "image/png": "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eL/+69OnT2AKL+l2LF++nNTUVC6//HLnsZSUFObMmcOnn37q0UHz448/ZubMmWRmZjqPTZ8+ncGDB/Phhx86j51yyikt4pf16NGDyZMns3fvXo9yPv744yiKQnZ2NvPnzychIYH4+Hiuu+46GhoaWqQ3GAysXLmSuXPnMmfOHAwGA59++qnHfCTtY/ny5ajVam666SbnscjISG644QZ+/PFH8vPzPV4/btw4xo0b5zw2dOhQzj77bJf200RFRQUPP/wwf/3rX0lISPBaTtl+gpPOaj81NTUApKamulzfNC7r9fo28+mO7Sekla19+/Zx6623MnHiRK699lrAUekAOp2uRfqm6LBNadzx4IMPUl1d7dd/nhpwONFQXdXVInQp27ZtY+zYsS1ii40fP56Ghga3K2ubKCgooLS0lFNPPbXFufHjx7Nt2zaP+RcXF5OcnOy1vHPmzKG2tpann36aOXPmsGTJEhYsWNAi3WeffUZdXR1z584lLS2NqVOnsmzZMq/zkXjHtm3bGDx4MHFxcS7Hx48fD8D27dtbvdZut7Nz585W28+hQ4eora11Of7II4+QlpbGH//4R5/kle0nuOis9nPqqacSHR3NI488wrp16ygoKODbb7/l/vvvZ9y4cUyfPt0rebtT+wmp1YjNKS4uZsaMGcTHxzu1dTiuMbuzEBiNRpc07tDpdG4VNYl/ePWmq5n18BP0HTXG7XkhBAaLrXOF8oBeq/bLRqXgsLyeeeaZLY43ffEVFhYyatSoVq9tnvbE65ustq21340bN/Ljjz/y8MMPey3vySefzBtvvOH8u7y8nDfeeINnnnnGJd3SpUuZNGmS04o7d+5cbrnlFsrKykhJSfE6v0AhhEC08ZHVFSh6fbvbVVFRUavPHxztpzWa2oen64cMGQLAzp07+c9//sMXX3zh7F/bSyi1H2sHwgL4G41O51Of1FntJzk5mQ8++IA//OEPnH322c505513HsuXL0ej8U416U7tJySVrerqai644AKqqqrYuHEjGRkZznNND91dcLKioiKSkpKkMtXFbF21slVly2CxMfzRrzpXIA/s+et5REX451UyGAw+W129tdq6O19aWsrvfvc7+vXrx/333++1vDfffLPL35MnT2blypXU1NQ4v47Ly8v56quv+Mc//uFMd8UVV3Drrbfy4Ycfcuutt3qdX6AQBgP7x57S1WK4MOTXX1Ciotp1TWe0nybuuOMOLrjgAs4999x2ydicUGk/VpOJl66d1dViOLnjreVofdjHrzPbT0pKCieffLIzNub27dtZuHAh1113HR999JFX8nan9hNyypbRaOSiiy7iwIEDrF27luHDh7uc79WrFykpKW6XuP/888+MGTOmkySVhCtms5mKigqXYykpKajVavR6vc9WV1+ttvX19cycOZPa2lo2bdrUrr0om/uGASQmJgJQWVnp7Ow++OADLBYLJ598MtnZ2c60EyZMYNmyZUExWIYKndV+PvjgA3744Qd27drVIXll+wkuOqv9HD58mGnTpvH2229zxRVXAHDJJZeQlZXF/PnzWb16NRdccIFHebtT+wkpZctms3HllVfy448/8umnnzJx4kS36a644greeust8vPznWbFb775hgMHDnDXXXd1psiSdqLXqtnz1/O6WgwX9Nr2TaH88MMPTJs2zeVYTk4OWVlZpKent2p1BVystCfii9XWbDZz+eWXs3PnTr766itn4F9vaW36SDQL/tfkG3H66ae7TXv48GH69+/frnz9jaLXM+TXX7pUhhNRPDgJuyM9PZ2CgoIWx71pP03tw5v2d9999zF79mwiIiLIzc0FHPHhAPLz8zGbzW3m1USotB+NTscdby3vUhmao/Fxdqaz2s+SJUswGo3MnDnTJd3FF18MwPfff++VstWd2k9IKVv33HMPn332GRdddBEVFRUsXbrU5fzVV18NwEMPPcRHH33EtGnTuPPOO6mrq2PRokWMGjWK6667ritEl3iJoih+m7LrKkaPHt0iSGBaWhoAY8aMYePGjdjtdhcn+c2bNxMVFcXgwYNbvW97rbZ2u5158+bxzTff8OGHHzJlypQOlMo9OTk5/PDDD9x2220t7m+327nmmmt499132+UnFggURWn3lF0wMmbMGNavX+8yjQKO9tN0vjVUKhWjRo1y2342b95M//79iY2NBRwK1bvvvsu7777bIu3YsWMZPXp0m87U3tKd2o8v03bBRme1n5KSEoQQ2Gyu/rcWiwUAq9Xa0aIAQdZ+2h+tIniZMmWKAFr915xdu3aJc889V0RFRYmEhATx+9//XhQXF3eJ3DKo6fE4W8/OmSGWP/WoECI842y9//77LeJslZWViYSEBHHllVe6pM3OzhbZ2dkux26++Wah1+tFXl6e89jatWsFIF599VWXtLfcckuL+Fve8thjj7mNqbR48WIBiJycHCGEEH/7298E4CJPc8455xwxdOjQducvcc9PP/3UIk6S0WgUAwcOFBMmTHBJe+TIEbF3716XY3//+98FILZs2eI8tm/fPqFWq8UDDzzgPLZy5coW/6688koBiLffflusW7euTTll+wlOOqv9PPvsswIQixcvdrn+hRdeEIB4//3325Szs9qPP+NsdW8TwQls2LDB67QjRozgq6+Cy9Fa0kgH9p/q7syaNYvTTjuN6667jj179pCcnMwrr7yCzWZrsaS5aRVP0zQOeG+1feGFF3jllVeYOHEiUVFRLazAl112GdHR0R0uz7JlyxgzZkyrseQuvvhibr/9dn799VfGjh3b4fzCnQkTJjB79mwefPBBSktLGThwIG+99Ra5ubkuq7YA5s2bx7fffusy5XLLLbfw3//+lxkzZnDvvfei1Wp5/vnnSU1N5Z577nGmu/TSS1vk3WTJuuCCC9oVPqQtZPvpXDqr/cyfP59nn32WP/7xj2zbto0RI0bw66+/8vrrrzNixAguu+wyv5QnmNpPSMfZknRvSnKqu1qETketVvPFF19w5ZVX8tJLL3HfffeRnJzMunXrnEvu26JPnz58++23DBgwgL/85S8sXLiQCy+8kK+//trFX6tpYPzxxx+55pprWvw7cS9FX/j111/Zt28fF110Uatpms6dqOxJfOftt9/mz3/+M++88w533HEHFouFVatWuQ0pciKxsbFs2LCBM888kyeeeIJHHnmE0aNH8+2333Z6iAXZfrqGzmg/PXr0YOvWrVx99dX873//4/bbb+ezzz7j+uuvZ8OGDURERHS4HMHWfhQhwtiMECTU1NQQHx9PdXV1i2By4cDRv2x0/v5BzjNkjTmFKx5cwMYVe4jqa2DYsGFEhYA/jUQikUi6Dw0NDezdu5fc3FwOHz7M8OHDmTFjhksab8dvadmSSCQSiUQiCSBS2ZJIJBKJRCIJIFLZkgQfTTPbcoJbIpFIJCGAVLYkEolEIpFIAohUtiQSiUQikUgCiFS2JMFH02717d+0XiKRSCSSoEMqW5LgRfpsSSQSiSQEkMqWRCKRSCQSSQCRypYk+JBxdiUSiUQSQkhlSyKRSCQSiSSASGVLIpFIJBKJJIBIZUsSfChyGaJEIpFIQgep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ACkpKQwZMqRFv/T++++jUqm44oornMeuuuoq7rnnHiorK0lMTAy4rO3Bq2nEw4cPc88997RL0WqOTqfjvvvuC+iydEkIEQbb9ej1ekwmU4vjTf4Ger2+zWsBn69vIjMzs8WxxMREKisrnX/bbDbef/99pk2bRk5ODtnZ2WRnZzNhwgRKSkr45ptvPOYj6Tw6q101/ZwzZ45T0QKYPXs2Go3G6xmME9tg0wDZvA1+8MEHWCwWTj75ZGf7q6ioYMKECXIq0c90pP34C2/6JXBYO8ePH095ebmzXZx88smYzWY++uijgMvZXryybJ04f+sr/rqPJDxwawTXRjksScGE1vN0yYmkp6dTUFDQ4nhRUREAGRmtW++SkpLQ6XTOtO29vonWLFKimbLbtNz+/fff5/3332+RdtmyZZx77rke8wp2NBEqbnpxSleL4YImov2ReTqrXTX9TE1NdUmnVqvp0aNHi4GxNbxpg00K1emnn+427eHDh+nfv79X+QUKRasi46+TulSG5iha36I6daT9+Atv2kRzn9FBgwa1SLts2TIXJ/9gwCtl67bbbuPGG29kzJgxARZHIjmOW/uWorR7yi4YGTNmDOvXr3eZLgHYvHmz83xrqFQqRo0axdatW1uc27x5M/379+/QiqDmLFu2jJ49e/Kvf/2rxbkVK1awcuVK/v3vf3fKF28gURSl3VN2wUhntatTTjkFoMXAbDabOXbsmN/8qHJycvjhhx+47bbbmDLFVRm22+1cc801vPvuuzz88MN+yc9XFEXxadou2OhI++lMli1bhlar5Z133mmhnG3atImXXnqJvLw8t1ayrsIr9feVV17hlFNOYezYsfzrX/+iqqoqwGJJJKHNrFmzsNlsvPbaa85jJpOJxYsXM2HCBKcjMEBeXh779u1rcf2WLVtcBsb9+/ezbt06vzmHGgwGVqxYwcyZM5k1a1aLf7fddhu1tbV89tlnfslP0nE6q11NnTqVnj17smzZMpel9kuWLMFms3HOOef4pTxNVq3777+/RfubM2cOU6ZMkVOJfqSj7aezWLZsGZMnT+bKK69s0S7uu+8+AN57770uka01vLJsXXTRRaxevZrt27dzxx13cN9993HZZZdx/fXXc/bZZwdaRkm4EQZ7I06YMIHZs2fz4IMPUlpaysCBA3nrrbfIzc11WZ0FMG/ePL799lsXM/ott9zCf//7X2bMmMG9996LVqvl+eefJzU1lXvuuccvMn722WfU1tZy8cUXuz1/2mmnkZKSwrJly7jyyiv9kqekY3RWu9LpdCxatIhrr72WM888k2uuuYa8vDxefPFFJk+ezOWXX+6X8ixbtowxY8a4DPLNufjii7n99tv59ddfGTt2rF/yDGc62n6qq6udq5a///57AF5++WUSEhJISEhwWeXsK5s3byY7O7vVe/Xq1YuxY8eybNkyHnjggQ7n5ze8jaRaUlIiFi5cKIYPHy4URRGKogiVSiWysrLEX//6V5GXl+d9WFaJCzKC/AkR5J96VAgR2hHkhXBEZr733ntFWlqa0Ol0Yty4ceLLL79skW7KlCnC3auan58vZs2aJeLi4kRMTIyYOXOmOHjwoFd5A+LWW29tcbxv377i2muvFUIIcdFFF4nIyMg263/+/PlCq9V2WhRxiWc6s1299957YvTo0UKn04nU1FRx2223OSOIt8Vjjz0mAFFWVuZyfPHixc6o47/88osAxCOPPNLqfXJzcwUg7rrrLo95SryjI+0nJydH4PAAafGvb9++HvPu27evmDFjhtu8pkyZIoQQ4vbbbxeAOHToUKv3efzxxwUgduzY4THPtvBnBHlFiPYv/dq8eTNvvPEGH374ITU1NY75akXhnHPO4frrr+fSSy9Fq9V2XBMME2pqaoiPj6e6ujosFxEc/ctG5+8f5DxD1uixXPHQX/nu4z1EZxkYNmyYVzF7JBKJRCLxFw0NDezdu5fc3FwOHz7M8OHDmTFjhksab8dvn5YsTJgwgddee43i4mLeeustzjzzTIQQfPXVV8ydO5eMjAzuuusufvvtN19uL5FIJBKJRBIy+LY+tJHIyEiuueYa1q9fT3Z2Ng8//DC9e/emvLycl156iTFjxjjD/EskEolEIpGEIx1StprTr18//vrXv5Kbm8vKlStJTk5GCMEvv/zirywkEolEIpFIuh1erUb0ls2bN/Pmm2/ywQcfODcslb5bEp8Jg0jyEolEIgl9OqxslZaW8vbbb7N48WL27dvnXAY6ZMgQbrjhBubNm9dhISUSiUQikUi6Kz4pWzabjVWrVrF48WJWr16N1WpFCEF0dDSzZ8/mxhtvZNKk4Nm6QNJNCYN4WxKJRCIJfdqlbO3du5c333yTpUuXUlpa6rRiTZgwgRtuuIG5c+cSExMTEEElYYicRpRIJBJJCOCVsvXaa6/x5ptvOjd+FELQo0cPrrnmGm644QZGjBgRUCElEolEIpFIuiteKVs333wz4NiodPr06dx4441ccskl0vldIpFIJBKJxANeKVuZmZlcf/31XHfdda3uUSWRSCQSiUQiaYlXylZOTg6KdFaWSCQSiUQiaTdeBTWVipZEIpFIJBKJb/gcZ6u6uppXXnmFb775hsLCQoxGo9t0iqJw6NAhnwWUSCQSiUQi6c74tF3P4cOHGTlyJA8//DDr1q1j37595ObmtvpPIpG0xGQy8cADD5CRkYFer2fChAl8/fXXXl9fUFDAnDlzSEhIIC4ujksuuYTDhw+7pMnPz2fBggWMHz+exMREkpOTmTp1KmvXrvV3cVwYP348iqLw6quvBjQfiUQi6Q74pGzdd999FBQUMHHiRD7++GN27txJTk6O238ndv4SicTB/Pnzef755/n973/Piy++iFqt5sILL2TTpk0er62rq2PatGl8++23PPTQQyxYsIBt27YxZcoUysvLnek+/fRTnnnmGQYOHMgTTzzBI488Qm1tLeeccw6LFy8OSLkOHjzIli1byMrKYtmyZQHJQyKRSLoTPk0jrlu3jszMTNauXUtkZKS/ZZKEOSIMgpn+/PPPvP/++yxatIh7770XgHnz5jFy5Ejuv/9+fvjhhzavf+WVVzh48CA///wz48aNA+CCCy5g5MiRPPfcczz11FMATJs2jby8PJKTk53X3nzzzYwZM4ZHH32U6667zu9lW7p0KT179uS5555j1qxZ5ObmkpWV5fd8JBKJpLvgk2XLZrMxYcIEqWhJAkI4LMhYvnw5arWam266yXksMjKSG264gR9//JH8/HyP148bN86paAEMHTqUs88+mw8//NB5bMSIES6KFoBOp+PCCy/k6NGjzg3jW2PJkiUoisL333/P3XffTUpKCtHR0Vx22WWUlZW5vebdd99l1qxZzJw5k/j4eN59990285BIJJJQxydla+TIkVRUVPhbFokkbNi2bRuDBw8mLi7O5fj48eMB2L59e6vX2u12du7cyamnntri3Pjx4zl06JBHJaq4uJioqCiioqK8kvf2229nx44dPPbYY/zpT3/if//7H7fddluLdJs3byY7O5urrrqKiIgILr/8cjmVKJFIwh6fphFvu+02rrvuOnbt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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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dU3TBx98AACIjIxEjx49YGBgAGtra+jpZe/BFAoFj0gREWlJbGwstm3bBl9fXxgZGckdh0inqdU0RUZGqv4vhEBaWhoeP36c41geKiYi0p5Vq1ZBX18fo0ePljsKkc5Tq2l6+PChpnMQEVEBJScnY9WqVfD09ISlpaXccYh0nlpNk4ODg6ZzEBFRAW3duhVxcXHw8fGROwpRqaDWheBERCSvjIwMLFmyBL169YKjo6PccYhKBbVv2EtERPI5duwY7ty5g/Xr18sdhajUkNQ0dezYEQqFAps3b4atrS06duwoeQcKhQKnTp1SOyAREWXn7+8PJycntGnTRu4oRKWGpKbpzJkzUCgUePv2reprqfjpOSIizYqIiMDp06exc+dOvscSFSFJTVNoaCgAwN7ePsvXRERU9Pz9/WFvb4++ffvKHYWoVJHUNDk7O+f5NRERFY3o6Gjs2LED33//PQwMeFkqUVFS69Nzc+fOxZIlSzSdhYiI8rFixQqYmprCy8tL7ihEpY7aTVNYWJimsxARUR6SkpKwZs0afP755zA3N5c7DlGpo1bTVKVKFZiammo6CxER5WHTpk1ITEzkZJZEMlGraWrbti2uXLmi6SxERJQLpVKJJUuWoH///qoP5RBR0VKrafr222/x9OlTfPPNNxBCaDoTERH9x8GDB/HgwQNMmTJF7ihEpZZaH7349ddfMXz4cCxatAh79+5Fr169UL169VxP2Q0fPrxQIXNz9epVbN68GaGhoYiMjETFihXx8ccfY/78+ahVq5ZW9klEJAc/Pz+0bdsWLVq0kDsKUamlVtPk4eEBhUIBIQT++usv/PDDD3mO11bT9P333+P8+fPo378/GjZsiGfPnmHFihVo2rQpLl26hPr162tlv0REReny5cs4f/489u3bJ3cUolJNraZp+PDhxWIW2ilTpmD79u0wMjJSLRs4cCAaNGiA7777Dtu2bZMxHRGRZvj7+8PR0RE9evSQOwpRqaZW07Rp0yYNx1BP69atsy378MMPUa9ePfz5558yJCIi0qzIyEgEBQVh2bJl0NfXlzsOUammc9PJCiEQGxuLevXq5TkuNTUVqampGt13QkICACAtLQ1paWka227mtjS5TV3FWhUM6yWdXLUKCAiAhYUFhgwZUmK+T3xdScdaSafNWkndpkLo2Mfftm3bhmHDhmHDhg3w9PTM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THj5X5s3bxZNmzYVJiYmwtzcXHTs2FGEhITkOalkcnKymD59unB0dBRGRkaqyRL/O7lkXh49eiR8fHzERx99JExMTETZsmVFrVq1hKenZ46TTF68eFF06dJFmJubC1NTU9GoUSOxatUqkZGRke/klnnlysyen9jYWDFr1izRtGlTUa5cOWFkZCRsbW1F69atxezZs8WNGzeyjM+c3PK/3+dMeU1i+ccffwg3NzdRuXJloaenl+P3PS/r1q0TAMT06dNzXP/+c169erVo3LixMDU1Febm5sLFxUWcP38+y/hZs2YJAKJ58+aS9r9//34BQFSoUEEkJyerlv/2228CgOjQoYPk50KkLQohCvDRGCLSCZs2bcLIkSMxYsQIbNq0Se44VAy8ffsW1atXh4GBASIjI7NNIJo5b1RR/8qYOHEiVqxYgQMHDuQ72SiRtvH0HBERwczMDAsWLEBMTAzWrVsndxwA/95TMTAwEO3bt2fDRMUCmyYiIgLw721NmjVrhvnz5+PNmzdyx8GcOXOQlpaGpUuXyh2FCACbJiIi+v/09PRw7do1PHv2LN9JOYtCYGAg0tPT0bBhQ7mjEAEAeE0TERERkQQ80kREREQkAZsmIiIiIgnYNBERERFJwKaJiIiISAI2TUREREQSsGkiIiIikoBNExEREZEEbJqIiIiIJGDTRERERCTB/wOJ8XCMti0dfgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{-0.02: 0.0, 0.0: 0.0, 0.02: 0.0, 0.04: 0.0, 0.06: 5.0, 0.08: 8.0, 0.1: 10.0}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "martinotti_cell = detailed_cell_doc.cells[0]\n", + "\n", + "generate_current_vs_frequency_curve(detailed_cell_file,\n", + " martinotti_cell.id,\n", + " start_amp_nA=-0.02,\n", + " end_amp_nA=0.1,\n", + " step_nA=0.02,\n", + " pre_zero_pulse=100,\n", + " post_zero_pulse=100,\n", + " analysis_duration=1000,\n", + " plot_voltage_traces=True,\n", + " simulator='jNeuroML_NEURON')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4) Create a small network using the cells\n", + "\n", + "### 4.1) Generate the NeuroML network\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" -validate NML_DB_network.net.nml ) in directory: .\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*******************************************************\n", + "* NeuroMLDocument: NML_DB_Net\n", + "*\n", + "* ExpOneSynapse: ['syn0']\n", + "* IncludeType: ['TestCell.cell.nml', 'bAC217_L23_MC_40be3bf0e8_0_0.cell.nml']\n", + "* PulseGenerator: ['pg_exc_0', 'pg_exc_1', 'pg_exc_2', 'pg_exc_3', 'pg_inh_0', 'pg_inh_1', 'pg_inh_2', 'pg_inh_3']\n", + "*\n", + "* Network: NML_DB_Net (temperature: 34.0degC)\n", + "*\n", + "* 8 cells in 2 populations \n", + "* Population: Exc with 4 components of type novel_cell\n", + "* Population: Inh with 4 components of type bAC217_L23_MC_40be3bf0e8_0_0\n", + "*\n", + "* 13 connections in 1 projections \n", + "* Projection: Proj_exc_inh from Exc to Inh, synapse: syn0\n", + "* 13 connections (wd): [(Connection 0: 0 -> 0, weight: 0.087187, delay: 0.00000 ms), ...]\n", + "*\n", + "* 0 inputs in 0 input lists \n", + "*\n", + "* 8 explicit inputs (outside of input lists)\n", + "* Explicit Input of type pg_exc_0 to Exc(cell 0), destination: unspecified\n", + "* Explicit Input of type pg_exc_1 to Exc(cell 1), destination: unspecified\n", + "* Explicit Input of type pg_exc_2 to Exc(cell 2), destination: unspecified\n", + "* Explicit Input of type pg_exc_3 to Exc(cell 3), destination: unspecified\n", + "* Explicit Input of type pg_inh_0 to Inh(cell 0), destination: unspecified\n", + "* Explicit Input of type pg_inh_1 to Inh(cell 1), destination: unspecified\n", + "* Explicit Input of type pg_inh_2 to Inh(cell 2), destination: unspecified\n", + "* Explicit Input of type pg_inh_3 to Inh(cell 3), destination: unspecified\n", + "*\n", + "*******************************************************\n", + "Written network file to: NML_DB_network.net.nml\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Command completed successfully!\n", + "pyNeuroML >>> INFO - Output: \n", + " jNeuroML >> jNeuroML v0.13.0\n", + " jNeuroML >> Validating: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/NML_DB_network.net.nml\n", + " jNeuroML >> Valid against schema and all tests\n", + " jNeuroML >> No warnings\n", + " jNeuroML >> \n", + " jNeuroML >> Validated 1 files: All valid and no warnings\n", + " jNeuroML >> \n", + " jNeuroML >> \n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "from neuroml.utils import component_factory\n", + "from pyneuroml import pynml\n", + "from pyneuroml.lems import LEMSSimulation\n", + "import neuroml.writers as writers\n", + "import random\n", + "\n", + "nml_doc = component_factory(\"NeuroMLDocument\", id=\"NML_DB_Net\")\n", + "\n", + "\n", + "### Create the network\n", + "net = nml_doc.add(\"Network\", id=\"NML_DB_Net\", validate=False)\n", + "net.type=\"networkWithTemperature\" \n", + "net.temperature=\"34.0degC\"\n", + "\n", + "### Add a synapse\n", + "syn0 = nml_doc.add(\n", + " \"ExpOneSynapse\", id=\"syn0\", gbase=\"65nS\", erev=\"0mV\", tau_decay=\"3ms\"\n", + ")\n", + "\n", + "\n", + "## Create the first population\n", + "size_exc = 4\n", + "nml_doc.add(\"IncludeType\", href=cell_file)\n", + "\n", + "pop_exc = component_factory(\"Population\", id=\"Exc\", component=cell.id, size=size_exc, type=\"population\")\n", + "# Set optional color property. Note: used later when generating plots\n", + "##pop0.add(\"Property\", tag=\"color\", value=\"0 0 .8\")\n", + "net.add(pop_exc)\n", + "\n", + "## Create the second population\n", + "size_inh = 4\n", + "nml_doc.add(\"IncludeType\", href=detailed_cell_file)\n", + "\n", + "pop_inh = component_factory(\"Population\", id=\"Inh\", component=detailed_cell.id, size=size_inh, type=\"population\")\n", + "# Set optional color property. Note: used later when generating plots\n", + "##pop1.add(\"Property\", tag=\"color\", value=\"0 0 .8\")\n", + "net.add(pop_inh)\n", + "\n", + "## Create connections and inputs\n", + "random.seed(123)\n", + "prob_connection = 0.8\n", + "\n", + "proj_count = 0\n", + "\n", + "projection = Projection(\n", + " id=\"Proj_exc_inh\",\n", + " presynaptic_population=pop_exc.id,\n", + " postsynaptic_population=pop_inh.id,\n", + " synapse=syn0.id,\n", + " )\n", + "\n", + "net.projections.append(projection)\n", + "\n", + "for i in range(0, size_exc):\n", + " for j in range(0, size_inh):\n", + " if random.random() <= prob_connection: # probablistic connection...\n", + " connection = ConnectionWD(\n", + " id=proj_count,\n", + " pre_cell_id=\"%s[%i]\" % (pop_exc.id, i),\n", + " post_cell_id=\"%s[%i]\" % (pop_inh.id, j),\n", + " weight=random.random(),\n", + " delay='0ms'\n", + " )\n", + " projection.add(connection)\n", + " proj_count += 1\n", + "\n", + "for i in range(0, size_exc):\n", + " # pulse generator as explicit stimulus\n", + " pg = nml_doc.add(\n", + " \"PulseGenerator\",\n", + " id=\"pg_exc_%i\" % i,\n", + " delay=\"20ms\",\n", + " duration=\"260ms\",\n", + " amplitude=\"%f nA\" % (0.03 + 0.01 * random.random()),\n", + " )\n", + " \n", + " exp_input = net.add(\n", + " \"ExplicitInput\", target=\"%s[%i]\" % (pop_exc.id, i), input=pg.id\n", + " )\n", + "\n", + "for i in range(0, size_inh):\n", + " # pulse generator as explicit stimulus\n", + " pg = nml_doc.add(\n", + " \"PulseGenerator\",\n", + " id=\"pg_inh_%i\"%i,\n", + " delay=\"20ms\",\n", + " duration=\"260ms\",\n", + " amplitude=\"%f nA\" % (0.02 + 0.02 * random.random()),\n", + " )\n", + " \n", + " exp_input = net.add(\n", + " \"ExplicitInput\", target=\"%s[%i]\" % (pop_inh.id, i), input=pg.id\n", + " )\n", + "\n", + "\n", + "print(nml_doc.summary())\n", + "\n", + "nml_net_file = 'NML_DB_network.net.nml'\n", + "writers.NeuroMLWriter.write(nml_doc, nml_net_file)\n", + "\n", + "print(\"Written network file to: \" + nml_net_file)\n", + "pynml.validate_neuroml2(nml_net_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.2) Generate views of the network " + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Converting NML_DB_network.net.nml to graphical form, level -1, engine dot\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "neuromllite >>> Initiating GraphViz handler, level -1, engine: dot, seed: 1234\n", + "Parsing: NML_DB_network.net.nml\n", + "Loaded: NML_DB_network.net.nml as NeuroMLDocument\n", + "neuromllite >>> Document: NML_DB_Net\n", + "neuromllite >>> Network: NML_DB_Net\n", + "neuromllite >>> Population: Exc, component: novel_cell (Cell), size: 4 cells, properties: {}\n", + "neuromllite >>> Population: Inh, component: bAC217_L23_MC_40be3bf0e8_0_0 (Cell), size: 4 cells, properties: {}\n", + "neuromllite >>> GRAPH PROJ: Proj_exc_inh (Exc (4) -> Inh (4), projection): w 1.0; wtot: 4.849021209484878; sign: 1; cond: 65.0 nS (65nS); all: {'projection': 58.85091239849243, 'inhibitory': -1e+100, 'excitatory': -1e+100, 'electricalProjection': -1e+100, 'continuousProjection': -1e+100} -> {'projection': 1.380338363104285, 'inhibitory': 1e+100, 'excitatory': 1e+100, 'electricalProjection': 1e+100, 'continuousProjection': 1e+100}\n", + "neuromllite >>> - conn Exc_0 -> Inh_0: 5.66713403897108 (5.66713403897108)\n", + "neuromllite >>> - conn Exc_0 -> Inh_1: 7.000515270998535 (7.000515270998535)\n", + "neuromllite >>> - conn Exc_0 -> Inh_3: 34.85313260220526 (34.85313260220526)\n", + "neuromllite >>> - conn Exc_1 -> Inh_0: 55.385630230408985 (55.385630230408985)\n", + "neuromllite >>> - conn Exc_1 -> Inh_1: 21.91908271210294 (21.91908271210294)\n", + "neuromllite >>> - conn Exc_1 -> Inh_2: 15.935617913644716 (15.935617913644716)\n", + "neuromllite >>> - conn Exc_1 -> Inh_3: 28.357926571989168 (28.357926571989168)\n", + "neuromllite >>> - conn Exc_2 -> Inh_0: 38.84396519171941 (38.84396519171941)\n", + "neuromllite >>> - conn Exc_2 -> Inh_1: 20.504833292831094 (20.504833292831094)\n", + "neuromllite >>> - conn Exc_2 -> Inh_2: 58.85091239849243 (58.85091239849243)\n", + "neuromllite >>> - conn Exc_2 -> Inh_3: 9.241379188047565 (9.241379188047565)\n", + "neuromllite >>> - conn Exc_3 -> Inh_0: 1.380338363104285 (1.380338363104285)\n", + "neuromllite >>> - conn Exc_3 -> Inh_2: 17.245910842001596 (17.245910842001596)\n", + "neuromllite >>> Generating graph for: NML_DB_Net\n", + "neuromllite >>> **************************************\n", + "neuromllite >>> * Settings for GraphVizHandler: \n", + "neuromllite >>> *\n", + "neuromllite >>> * engine: dot\n", + "neuromllite >>> * level: -1\n", + "neuromllite >>> * is_cell_level: True\n", + "neuromllite >>> * CUTOFF_INH_SYN_MV: -50\n", + "neuromllite >>> * include_ext_inputs: True\n", + "neuromllite >>> * include_input_pops: True\n", + "neuromllite >>> * scale_by_post_pop_size: True\n", + "neuromllite >>> * scale_by_post_pop_cond: True\n", + "neuromllite >>> * min_weight_to_show: 0\n", + "neuromllite >>> * show_chem_conns: True\n", + "neuromllite >>> * show_elect_conns: True\n", + "neuromllite >>> * show_cont_conns: True\n", + "neuromllite >>> * output_format: png\n", + "neuromllite >>> *\n", + "neuromllite >>> * Used values: \n", + "neuromllite >>> * syn_conds_used: syn0:\t 65.0 nS (65nS)\n", + "neuromllite >>> *\n", + "neuromllite >>> **************************************\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/subprocess.py:1052: ResourceWarning: subprocess 25497 is still running\n", + " _warn(\"subprocess %s is still running\" % self.pid,\n", + "ResourceWarning: Enable tracemalloc to get the object allocation traceback\n", + "pyNeuroML >>> INFO - Done with GraphViz...\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": { + "image/png": { + "width": 500 + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "from pyneuroml.pynml import generate_nmlgraph\n", + "\n", + "generate_nmlgraph(nml_net_file, level=-1, engine=\"dot\")\n", + "\n", + "from IPython.display import Image\n", + "Image(filename='%s.gv.png'%net.id,width=500)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.3) Generate LEMS file to simulate the network\n", + "\n", + "See documentation about [LEMS Simulation files](https://docs.neuroml.org/Userdocs/LEMSSimulation.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saved LEMS Simulation file to: LEMS_NML_DB_network_sim.xml\n" + ] + } + ], + "source": [ + "simulation_id = \"NML_DB_network_sim\"\n", + "simulation = LEMSSimulation(sim_id=simulation_id,\n", + " duration=300, dt=0.025, simulation_seed=123)\n", + "simulation.assign_simulation_target(net.id)\n", + "simulation.include_neuroml2_file(nml_net_file, include_included=False)\n", + "\n", + "\n", + "pops = [pop_exc, pop_inh]\n", + "\n", + "for pop in pops:\n", + " simulation.create_event_output_file(\n", + " f\"{pop.id}_spikes\", f\"{pop.id}.spikes\", format='ID_TIME'\n", + " )\n", + " simulation.create_output_file(pop.id, \"%s.v.dat\" % pop.id)\n", + "\n", + " for pre in range(0, pop.size):\n", + " next_cell = '{}[{}]'.format(pop.id,pre)\n", + " simulation.add_selection_to_event_output_file(\n", + " f\"{pop.id}_spikes\", pop.component, next_cell, 'spike')\n", + "\n", + " simulation.add_column_to_output_file(pop.id, f\"v{pre}\", f\"{next_cell}/v\")\n", + " \n", + " \n", + "lems_simulation_file = simulation.save_to_file()\n", + "\n", + "print(f\"Saved LEMS Simulation file to: {lems_simulation_file}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.4) Run simulation of the network using NEURON" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading LEMS file: LEMS_NML_DB_network_sim.xml and running with jNeuroML_NEURON\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx2G -Djava.awt.headless=true -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" LEMS_NML_DB_network_sim.xml -neuron -run -compile -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n", + "pyNeuroML >>> WARNING - Reloading: Data loaded from ./Exc.v.dat (jNeuroML_NEURON)\n", + "pyNeuroML >>> WARNING - Reloading: Data loaded from ./Inh.v.dat (jNeuroML_NEURON)\n" + ] + }, + { + "data": { + "image/png": "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CSec4CrjF7/4BQ499NDY6054U+42NHnyZHz729/GgQceCMuycNJJJ2nPP+OMMzBp0iScc845rjLuuecedO3alUI3lphytqGNGzdi4sSJOPHEE9GrVy9069YNxxxzDCZPnqycT22o9VLufuiKK67AkUceie7du6NDhw445JBDcPPNN2P79u3CcW2xDVWVuwIE0dpgjPkfVIH85je/wf7776/sP+CAAxKR9+1vf1vZt2rVKpx44ono2rUrbrvtNmzfvh133HEHFi1ahHnz5jnJfvbee298+9vfRktLC+6//35t+dOmTcPw4cOx1157JVJ/wpvW0J6mT5+OBx98EEOHDsWAAQOwdOlS7bl77LEHvv3tb2PWrFm47bbbtMdMmzYNe+65J44++uhY602YUe72tHPnTowfPx7HHHMMfvjDH2LPPffEnDlzcNNNN+GVV17Bq6++6hjHqD21fsrdngBg4cKF2H///fGVr3wFe+yxBz7//HM88MADeP755/H++++jb9++AKg9EUSlwPj1E7vpXKM10Lt3b22f/MILL+Dss8/GSSedhHvuuQeLFi3Crbfeivr6evztb39zjhs+fDiGDx+Ol19+Ge+++65WxrRp0/DlL385sWsgyotbG/rb3/6Gd955B0cffTQ2btzoev6gQYMwaNAgfPrpp/jXv/6lPWbatGk47bTTUF1dHVu9idaDrg3NmTMHv/71rzF27Fhcf/31qKqqwtNPP40LL7wQixcvxi233OIcS22IcOuH5s+fjxNOOAHjx49HTU0NFi5ciN///vd4+eWX8cYbbyCVyvkvtMU2VHHGi6amJtx4442YNGkSNm/ejKFDh+LWW2/FmDFjfM9dvXo1rrjiCsyYMQO2bWP06NG4++67MWDAAOeYlStX4uGHH8a0adOwbNkypNNpDB48GNdffz1OPfXUJC+NIBLlzDPPxFFHHVXWOtx2223YsWMH3nnnHeyzzz4AgBEjRmDMmDF49NFHPT0tZKZPn47vfS9aUkQiPK2hPf3oRz/CL3/5S9TW1uInP/mJq/HChOnTp+PMM8+kRJllotztqV27dnj77bdx3HHHOfsuueQS7Lfffo4BI8gYgNpTeSl3ewKAe++9V9l39tln46ijjsLjjz+OX/3qV8ZlUXsiiDYGGS9aHVdddRWGDh2KGTNmoKoqpyLp0qULbrvtNlx++eUYNGiQUTmfffYZPvnkE/z9739PsrpEK2TSpEno168fUqkUBg8eHLqcnTt34vXXXxeMZkTlc9hhh2HZsmXYd999nX2XXXYZTj31VPzhD3/ANddcg44dOxqVRW1o9+Wtt95S9g0cOBBXXXUV5s2bh2OOOcaonNbYhioubNTFF1+Mu+66C9/61rfw5z//Gel0GmPHjtU+RJ7t27dj9OjReP3113HdddfhlltuwcKFCzFq1CjBcv7vf/8bf/jDH3DAAQfg1ltvxQ033IBt27ZhzJgxeOSRR5K+PKIE0ORf5aabbkIqlcIrr7wi7L/00kvRrl07vP/++86+1atXY8KECejbt68TCuNHP/oRmpubfeU8/fTTOOussxzDBQCceuqpOOiggzBlyhTj+i5atAgrV67EuHHjsG7dOlRVVQmrFQp88sknsCwL/+///T/jsonolKo99e7dG7W1tZHru2XLFsyePRvjxo1DJpNB9+7dMX78eOW4hoYG1NTUaEMREMlRivbUrl07wXBRoOBqu2TJEuP6Untq3ZSqf9Kx3377Aci1EVOoPRFE22N39fIOwsUXX4xOnTph9erVOPvss9GpUyf06tULV111FbLZrPac+++/HwMHDkT79u1x9NFHY/78+UayFi9ejMWLF+PSSy91DBdATnHIGAuUa2jatGno2rUrjj/+eEydOhWWZeH1119XjrvvvvtgWRY+/PBD47KJYJSyDQFA//79nVXNUXjllVfQ1NSEM888EwsWLIBlWXjssceU41566SVYloXnn38+skxCTynb0P777y8YLoCcXurss89GU1MTPvvsM+N6UxtqPZS6H9IRZn7RGttQRXlezJs3D08++SQmTpzoTM4uuugiDB48GNdccw1mz57teu69996LZcuWYd68eY7b/ZlnnonBgwfjzjvvdFz1R48ejRUrVqBnz57OuT/84Q8xbNgw3HjjjdoJI9G2sDib3u40udi6dauSqMeyLPTo0QPXX389/vOf/2DChAlYtGgROnfujJdeegkPPPAAfvvb3+Lwww8HAKxZswYjRozAli1bcOmll2LQoEFYvXo1pk6dip07dzphn3SsXr0a9fX12tWwI0aMwPTp042vZfr06dhzzz1x1FFHwbIsjBo1ClOmTMFNN90kHDd58mSk02mcf/75xmUTZpS7PcVJ4aNccJs855xz8Mwzz+C+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ZEdpOHnyZPTs2RMnn3xyyeq2u1KuNvTTn/4UL774Ih5//HEnZKkJ1IZaH6VuQ126dHG8zL/61a/in//8J7761a/i3XffNWpLrbUNVZTxwm1VNr9q2+08wH/Ft46dO3fi/PPPR21tLX7/+9971u/222/XJg2OgxkzZpTN62PmzJllkZsUjTt3OansX5oxA19d8QfgxPuEY2qr01j8m9YVG7C22t1wFhefffYZli1bBiCXFDtOCobCgus2T11dHbp3724UMmr69OlCCI0CF154IcaPH4/33nsPw4YNw5QpU3DKKacEih+ZKNUdciuNWgsxrlZxI8n2FBfTp0/HfvvtJygugVx7uu+++/DCCy/g7LPPxpQpUzBo0KBAg8skqa2qxdxvzi13NRxqq6InTvejVO1p5syZuOiiizBu3Dj8/e9/D3RuW21PVm0tDn73nXJXw8EyVCRFoRz908CBA3HEEUfgH//4h5HxIsn2tHr1aqxfvx4vv/yy8O3dubOVhRchiDYCgyX8ioNKn494LQo0PdYkjB8/B5GjNNTV1RnHCZfDbAA5/cLZZ5+Nf/3rX7j33nuxbt06vP32205I6rLT2uYfQKxzkFK1obiYPn06zjjjDMWD84ILLsDvfvc7bNiwAZ07d8Zzzz2Hb3zjG0KC+XLR2uYcQLzzjnK0oVtuuQX33nsvfv/73+M73/lOoHPbYhtqbfMMIN65Rrn7oXPPPRff+c538OSTTxrNBVprGyp/S42R2traUKu2w674zmazuPDCC7F48WK88MIL6NvX2+Xy2muvxZVXXul9EQFpaGhA//79cdpppynhspImk8lg5syZGDNmTNnj5MXJ3/41CVvytqoxY8YAD/1WOcayrFhdotsCtm3j4osvRpcuXfDzn/8ct912G8477zzHc6FXr17o0qULPvzww1Dl9+vXD7169cKCBQuUv82bNw/Dhg3zLYMxhhdffFEbGuPss8/GD37wA0yePBkAsHTpUlx77bWh6poIlhWri3RrJ+n2FBfTpk3D2LFjlf0nnngi+vTpg8mTJ+P444/Hq6++il//+tdlqKEey7JidZdu7ZSqPc2dOxfnnHMOjjrqKEyZMiXwYK0tt6c4XadbO+XsnxobG429dJNsT/369UNNTQ1OPfVUIWyqafgUgiBELN54EVPOi91xPpIEhTnGggULBEPFmjVrsGrV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FwShwCfspskFQRAEQRDE7kpTUxN++ctfom/fvqitrcXIkSMxc+ZMo3NXr16Nr3/96+jWrRu6dOmCr371q04elAIrV67ELbfcghEjRmCPPfZAz549cdJJJ+Hll19O4nKIMmH5H0IQBEEQBEFoIOMFQXhgMwYwGwBAue0JgiAIgqhkaKyjcvHFF+Ouu+7Ct771Lfz5z39GOp3G2LFj8dZbb3met337dowePRqvv/46rrvuOtxyyy1YuHAhRo0ahY0bNzrH/fvf/8Yf/vAHHHDAAbj11ltxww03YNu2bRgzZgweeeSRpC+PKBGpmMJG0TtKEARBEERbIa5xCyXsJggF3vMCqG7aBADIZDLlqhBBEARBEETiNDc3AwBaWlrKXJPWwbx58/Dkk09i4sSJuOqqqwAAF110EQYPHoxrrrkGs2fPdj333nvvxbJlyzBv3jwcffTRAIAzzzwTgwcPxp133onbbrsNADB69GisWLECPXv2dM794Q9/iGHDhuHGG2/E+PHjE7xConTwCbuDT+Srq6sB0HyEIAiCIIi2Q1xzC/K8IAhPGKqatqAqsw2buFVyBEEQBEEQlQRjDBs2bEBzczMpSPNMnToV6XQal156qbOvpqYGEyZMwJw5c7By5UrPc48++mjHcAEAgwYNwimnnIIpU6Y4+w477DDBcAEA7du3x9ixY7Fq1Sps27YtxisiyoXFonleVFVVoaqqCps2bYqxVgRBEARBEMkQ59yCPC8IQkH0vLDA0G/xffji8KtQV1eHLl26wLIoci1BEARBEG0fxhiam5uxYcMGbN26FRs2bABjDKlUCqnU7r3OaeHChTjooIPQpUsXYf+IESMAAO+99x769++vnGfbNj744AN873vfU/42YsQIzJgxA9u2bUPnzp1dZa9duxYdOnRAhw4dIl4F0eoIYbywLAv9+vXDF198QfMRgiAIgiBaLUnMLch4QRASliZhd48VL2LVxiOxetQorEmny1U1giAIgiCIRChMMrZt24bt27djr732Qm1tbbmrVVbq6urQp08fZX9h35o1a7Tnbdq0CU1NTb7nHnzwwdrzP/30UzzzzDM4//zzkfYYdzY1NaGpqcn3OoLQ0NAAIBeeqNQeOAV5lej5I+S8sMNdY5cuXbDHHntg9erVrm2PIAiCIAiiNdDU1IT169dj27ZtaGhoQO/evVFVVSWM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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "traces = pynml.run_lems_with_jneuroml_neuron(\n", + " lems_simulation_file, max_memory=\"2G\", nogui=True, load_saved_data=True, plot=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/Userdocs/NML2_examples/OLM.ipynb b/_sources/Userdocs/NML2_examples/OLM.ipynb new file mode 100644 index 00000000..afd144bb --- /dev/null +++ b/_sources/Userdocs/NML2_examples/OLM.ipynb @@ -0,0 +1,660 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Interactive multi-compartment OLM cell example\n", + "\n", + "To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see {ref}`how to use this documentation `. Please uncomment the line below if you use the Google Colab. (It does not include these packages by default)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#%pip install pyneuroml neuromllite NEURON" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#!/usr/bin/env python3\n", + "\"\"\"\n", + "Multi-compartmental OLM cell example\n", + "\n", + "File: olm-example.py\n", + "\n", + "Copyright 2023 NeuroML contributors\n", + "Authors: Padraig Gleeson, Ankur Sinha\n", + "\"\"\"\n", + "\n", + "import neuroml\n", + "from neuroml import NeuroMLDocument\n", + "from neuroml.utils import component_factory\n", + "from pyneuroml import pynml\n", + "from pyneuroml.lems import LEMSSimulation\n", + "from pyneuroml.plot.PlotMorphology import plot_2D\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The CellBuilder module file can be found in the same folder as the Python script. It is used to define the helper functions that we use in our main file.\n", + "\n", + "## Declaring the NeuroML model\n", + "### Create the cell\n", + "\n", + "In this example, we do not create the ion channels. We include ion channels that are already provided in NeuroML files. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def create_olm_cell():\n", + " \"\"\"Create the complete cell.\n", + "\n", + " :returns: cell object\n", + " \"\"\"\n", + " nml_cell_doc = component_factory(\"NeuroMLDocument\", id=\"oml_cell\")\n", + " cell = nml_cell_doc.add(\"Cell\", id=\"olm\", neuro_lex_id=\"NLXCELL:091206\") # type neuroml.Cell\n", + " nml_cell_file = cell.id + \".cell.nml\"\n", + "\n", + " cell.summary()\n", + " cell.info(show_contents=True)\n", + " cell.morphology.info(show_contents=True)\n", + "\n", + " # Add two soma segments to an unbranched segment group\n", + " cell.add_unbranched_segment_group(\"soma_0\")\n", + " diam = 10.0\n", + " soma_0 = cell.add_segment(\n", + " prox=[0.0, 0.0, 0.0, diam],\n", + " dist=[0.0, 10., 0.0, diam],\n", + " name=\"Seg0_soma_0\",\n", + " group_id=\"soma_0\",\n", + " seg_type=\"soma\"\n", + " )\n", + "\n", + " soma_1 = cell.add_segment(\n", + " prox=None,\n", + " dist=[0.0, 10. + 10., 0.0, diam],\n", + " name=\"Seg1_soma_0\",\n", + " parent=soma_0,\n", + " group_id=\"soma_0\",\n", + " seg_type=\"soma\"\n", + " )\n", + "\n", + " # Add axon segments\n", + " diam = 1.5\n", + " cell.add_unbranched_segments(\n", + " [\n", + " [0.0, 0.0, 0.0, diam],\n", + " [0.0, -75, 0.0, diam],\n", + " [0.0, -150, 0.0, diam],\n", + " ],\n", + " parent=soma_0,\n", + " fraction_along=0.0,\n", + " group_id=\"axon_0\",\n", + " seg_type=\"axon\"\n", + " )\n", + "\n", + " # Add 2 dendrite segments, using the branching utility function\n", + "\n", + " diam = 3.0\n", + " cell.add_unbranched_segments(\n", + " [\n", + " [0.0, 20.0, 0.0, diam],\n", + " [100, 120, 0.0, diam],\n", + " [177, 197, 0.0, diam],\n", + " ],\n", + " parent=soma_1,\n", + " fraction_along=1.0,\n", + " group_id=\"dend_0\",\n", + " seg_type=\"dendrite\"\n", + " )\n", + "\n", + " cell.add_unbranched_segments(\n", + " [\n", + " [0.0, 20.0, 0.0, diam],\n", + " [-100, 120, 0.0, diam],\n", + " [-177, 197, 0.0, diam],\n", + " ],\n", + " parent=soma_1,\n", + " fraction_along=1.0,\n", + " group_id=\"dend_1\",\n", + " seg_type=\"dendrite\"\n", + " )\n", + "\n", + " # color groups for morphology plots\n", + " den_seg_group = cell.get_segment_group(\"dendrite_group\")\n", + " den_seg_group.add(\"Property\", tag=\"color\", value=\"0.8 0 0\")\n", + "\n", + " ax_seg_group = cell.get_segment_group(\"axon_group\")\n", + " ax_seg_group.add(\"Property\", tag=\"color\", value=\"0 0.8 0\")\n", + "\n", + " soma_seg_group = cell.get_segment_group(\"soma_group\")\n", + " soma_seg_group.add(\"Property\", tag=\"color\", value=\"0 0 0.8\")\n", + "\n", + " # Other cell properties\n", + " cell.set_init_memb_potential(\"-67mV\")\n", + " cell.set_resistivity(\"0.15 kohm_cm\")\n", + " cell.set_specific_capacitance(\"1.3 uF_per_cm2\")\n", + "\n", + " # channels\n", + " # leak\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"leak_all\",\n", + " cond_density=\"0.01 mS_per_cm2\",\n", + " ion_channel=\"leak_chan\",\n", + " ion_chan_def_file=\"olm-example/leak_chan.channel.nml\",\n", + " erev=\"-67mV\",\n", + " ion=\"non_specific\")\n", + " # HCNolm_soma\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"HCNolm_soma\",\n", + " cond_density=\"0.5 mS_per_cm2\",\n", + " ion_channel=\"HCNolm\",\n", + " ion_chan_def_file=\"olm-example/HCNolm.channel.nml\",\n", + " erev=\"-32.9mV\",\n", + " ion=\"h\",\n", + " group_id=\"soma_group\")\n", + " # Kdrfast_soma\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"Kdrfast_soma\",\n", + " cond_density=\"73.37 mS_per_cm2\",\n", + " ion_channel=\"Kdrfast\",\n", + " ion_chan_def_file=\"olm-example/Kdrfast.channel.nml\",\n", + " erev=\"-77mV\",\n", + " ion=\"k\",\n", + " group_id=\"soma_group\")\n", + " # Kdrfast_dendrite\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"Kdrfast_dendrite\",\n", + " cond_density=\"105.8 mS_per_cm2\",\n", + " ion_channel=\"Kdrfast\",\n", + " ion_chan_def_file=\"olm-example/Kdrfast.channel.nml\",\n", + " erev=\"-77mV\",\n", + " ion=\"k\",\n", + " group_id=\"dendrite_group\")\n", + " # Kdrfast_axon\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"Kdrfast_axon\",\n", + " cond_density=\"117.392 mS_per_cm2\",\n", + " ion_channel=\"Kdrfast\",\n", + " ion_chan_def_file=\"olm-example/Kdrfast.channel.nml\",\n", + " erev=\"-77mV\",\n", + " ion=\"k\",\n", + " group_id=\"axon_group\")\n", + " # KvAolm_soma\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"KvAolm_soma\",\n", + " cond_density=\"4.95 mS_per_cm2\",\n", + " ion_channel=\"KvAolm\",\n", + " ion_chan_def_file=\"olm-example/KvAolm.channel.nml\",\n", + " erev=\"-77mV\",\n", + " ion=\"k\",\n", + " group_id=\"soma_group\")\n", + " # KvAolm_dendrite\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"KvAolm_dendrite\",\n", + " cond_density=\"2.8 mS_per_cm2\",\n", + " ion_channel=\"KvAolm\",\n", + " ion_chan_def_file=\"olm-example/KvAolm.channel.nml\",\n", + " erev=\"-77mV\",\n", + " ion=\"k\",\n", + " group_id=\"dendrite_group\")\n", + " # Nav_soma\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"Nav_soma\",\n", + " cond_density=\"10.7 mS_per_cm2\",\n", + " ion_channel=\"Nav\",\n", + " ion_chan_def_file=\"olm-example/Nav.channel.nml\",\n", + " erev=\"50mV\",\n", + " ion=\"na\",\n", + " group_id=\"soma_group\")\n", + " # Nav_dendrite\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"Nav_dendrite\",\n", + " cond_density=\"23.4 mS_per_cm2\",\n", + " ion_channel=\"Nav\",\n", + " ion_chan_def_file=\"olm-example/Nav.channel.nml\",\n", + " erev=\"50mV\",\n", + " ion=\"na\",\n", + " group_id=\"dendrite_group\")\n", + " # Nav_axon\n", + " cell.add_channel_density(nml_cell_doc,\n", + " cd_id=\"Nav_axon\",\n", + " cond_density=\"17.12 mS_per_cm2\",\n", + " ion_channel=\"Nav\",\n", + " ion_chan_def_file=\"olm-example/Nav.channel.nml\",\n", + " erev=\"50mV\",\n", + " ion=\"na\",\n", + " group_id=\"axon_group\")\n", + "\n", + " cell.optimise_segment_groups()\n", + " cell.validate(recursive=True)\n", + " pynml.write_neuroml2_file(nml_cell_doc, nml_cell_file, True, True)\n", + " plot_2D(nml_cell_file, plane2d=\"xy\", nogui=True,\n", + " save_to_file=\"olm.cell.xy.png\")\n", + " return nml_cell_file" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create the network" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def create_olm_network():\n", + " \"\"\"Create the network\n", + "\n", + " :returns: name of network nml file\n", + " \"\"\"\n", + " net_doc = NeuroMLDocument(id=\"network\",\n", + " notes=\"OLM cell network\")\n", + " net_doc_fn = \"olm_example_net.nml\"\n", + " net_doc.add(\"IncludeType\", href=create_olm_cell())\n", + " net = net_doc.add(\"Network\", id=\"single_olm_cell_network\", validate=False)\n", + " # Create a population: convenient to create many cells of the same type\n", + " pop = net.add(\"Population\", id=\"pop0\", notes=\"A population for our cell\",\n", + " component=\"olm\", size=1, type=\"populationList\",\n", + " validate=False)\n", + " pop.add(\"Instance\", id=0, location=component_factory(\"Location\", x=0., y=0., z=0.))\n", + " # Input\n", + " net_doc.add(\"PulseGenerator\", id=\"pg_olm\", notes=\"Simple pulse generator\", delay=\"100ms\", duration=\"100ms\", amplitude=\"0.08nA\")\n", + "\n", + " net.add(\"ExplicitInput\", target=\"pop0[0]\", input=\"pg_olm\")\n", + "\n", + " pynml.write_neuroml2_file(nml2_doc=net_doc, nml2_file_name=net_doc_fn, validate=True)\n", + " return net_doc_fn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot the data we record" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_data(sim_id):\n", + " \"\"\"Plot the sim data.\n", + "\n", + " Load the data from the file and plot the graph for the membrane potential\n", + " using the pynml generate_plot utility function.\n", + "\n", + " :sim_id: ID of simulaton\n", + "\n", + " \"\"\"\n", + " data_array = np.loadtxt(sim_id + \".dat\")\n", + " pynml.generate_plot([data_array[:, 0]], [data_array[:, 1]], \"Membrane potential (soma seg 0)\", show_plot_already=False, save_figure_to=sim_id + \"_seg0_soma0-v.png\", xaxis=\"time (s)\", yaxis=\"membrane potential (V)\")\n", + " pynml.generate_plot([data_array[:, 0]], [data_array[:, 2]], \"Membrane potential (soma seg 1)\", show_plot_already=False, save_figure_to=sim_id + \"_seg1_soma0-v.png\", xaxis=\"time (s)\", yaxis=\"membrane potential (V)\")\n", + " pynml.generate_plot([data_array[:, 0]], [data_array[:, 3]], \"Membrane potential (axon seg 0)\", show_plot_already=False, save_figure_to=sim_id + \"_seg0_axon0-v.png\", xaxis=\"time (s)\", yaxis=\"membrane potential (V)\")\n", + " pynml.generate_plot([data_array[:, 0]], [data_array[:, 4]], \"Membrane potential (axon seg 1)\", show_plot_already=False, save_figure_to=sim_id + \"_seg1_axon0-v.png\", xaxis=\"time (s)\", yaxis=\"membrane potential (V)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create and run the simulaton" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def main():\n", + " \"\"\"Main function\n", + "\n", + " Include the NeuroML model into a LEMS simulation file, run it, plot some\n", + " data.\n", + " \"\"\"\n", + " # Simulation bits\n", + " sim_id = \"olm_example_sim\"\n", + " simulation = LEMSSimulation(sim_id=sim_id, duration=600, dt=0.01, simulation_seed=123)\n", + " # Include the NeuroML model file\n", + " simulation.include_neuroml2_file(create_olm_network())\n", + " # Assign target for the simulation\n", + " simulation.assign_simulation_target(\"single_olm_cell_network\")\n", + "\n", + " # Recording information from the simulation\n", + " simulation.create_output_file(id=\"output0\", file_name=sim_id + \".dat\")\n", + " simulation.add_column_to_output_file(\"output0\", column_id=\"pop0_0_v\", quantity=\"pop0[0]/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg0_soma_0\",\n", + " quantity=\"pop0/0/olm/0/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg1_soma_0\",\n", + " quantity=\"pop0/0/olm/1/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg0_axon_0\",\n", + " quantity=\"pop0/0/olm/2/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg1_axon_0\",\n", + " quantity=\"pop0/0/olm/3/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg0_dend_0\",\n", + " quantity=\"pop0/0/olm/4/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg1_dend_0\",\n", + " quantity=\"pop0/0/olm/6/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg0_dend_1\",\n", + " quantity=\"pop0/0/olm/5/v\")\n", + " simulation.add_column_to_output_file(\"output0\",\n", + " column_id=\"pop0_0_v_Seg1_dend_1\",\n", + " quantity=\"pop0/0/olm/7/v\")\n", + " # Save LEMS simulation to file\n", + " sim_file = simulation.save_to_file()\n", + "\n", + " # Run the simulation using the NEURON simulator\n", + " pynml.run_lems_with_jneuroml_neuron(sim_file, max_memory=\"2G\", nogui=True,\n", + " plot=False, skip_run=False)\n", + " # Plot the data\n", + " plot_data(sim_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -jar \"/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar\" -validate \"olm.cell.nml\" ) in directory: .\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*******************************************************\n", + "* Cell: olm\n", + "* Notes: None\n", + "* Segments: 0\n", + "* SegmentGroups: 4\n", + "*******************************************************\n", + "Cell -- Cell with **segment** s specified in a **morphology** element along with details on its **biophysicalProperties** . NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v** of this cell represents the membrane potential in that isopotential segment.\n", + "\n", + "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n", + "\n", + "Valid members for Cell are:\n", + "* morphology_attr (class: NmlId, Optional)\n", + "* biophysical_properties_attr (class: NmlId, Optional)\n", + "* morphology (class: Morphology, Optional)\n", + "\t* Contents ('ids'/): 'morphology'\n", + "\n", + "* neuro_lex_id (class: NeuroLexId, Optional)\n", + "\t* Contents ('ids'/): NLXCELL:091206\n", + "\n", + "* biophysical_properties (class: BiophysicalProperties, Optional)\n", + "\t* Contents ('ids'/): 'biophys'\n", + "\n", + "* annotation (class: Annotation, Optional)\n", + "* properties (class: Property, Optional)\n", + "* notes (class: xs:string, Optional)\n", + "* id (class: NmlId, Required)\n", + "\t* Contents ('ids'/): olm\n", + "\n", + "* metaid (class: MetaId, Optional)\n", + "\n", + "Morphology -- The collection of **segment** s which specify the 3D structure of the cell, along with a number of **segmentGroup** s\n", + "\n", + "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n", + "\n", + "Valid members for Morphology are:\n", + "* segments (class: Segment, Required)\n", + "* segment_groups (class: SegmentGroup, Optional)\n", + "\t* Contents ('ids'/): ['all', 'soma_group', 'axon_group', 'dendrite_group']\n", + "\n", + "* annotation (class: Annotation, Optional)\n", + "* properties (class: Property, Optional)\n", + "* notes (class: xs:string, Optional)\n", + "* id (class: NmlId, Required)\n", + "\t* Contents ('ids'/): morphology\n", + "\n", + "* metaid (class: MetaId, Optional)\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Command completed. Output: \n", + " jNeuroML >> jNeuroML v0.12.0\n", + " jNeuroML >> Validating: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.cell.nml\n", + " jNeuroML >> Valid against schema and all tests\n", + " jNeuroML >> No warnings\n", + " jNeuroML >> \n", + " jNeuroML >> Validated 1 files: All valid and no warnings\n", + " jNeuroML >> \n", + " jNeuroML >> \n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: olm.cell.nml\n", + "pyNeuroML >>> INFO - Including included files (included already: [])\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml\n", + "pyNeuroML >>> INFO - Including included files (included already: [])\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml\n", + "pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml'])\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml\n", + "pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml'])\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/KvAolm.channel.nml\n", + "pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml'])\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Nav.channel.nml\n", + "pyNeuroML >>> INFO - Including included files (included already: ['/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml', '/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/KvAolm.channel.nml'])\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx400M -jar \"/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar\" -validate \"olm_example_net.nml\" ) in directory: .\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saved image on plane xy to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.cell.xy.png of plot: 2D plot of olm from olm.cell.nml\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Command completed. Output: \n", + " jNeuroML >> jNeuroML v0.12.0\n", + " jNeuroML >> Validating: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_net.nml\n", + " jNeuroML >> Valid against schema and all tests\n", + " jNeuroML >> No warnings\n", + " jNeuroML >> \n", + " jNeuroML >> Validated 1 files: All valid and no warnings\n", + " jNeuroML >> \n", + " jNeuroML >> \n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_net.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.cell.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/leak_chan.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/HCNolm.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Kdrfast.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/KvAolm.channel.nml\n", + "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm-example/Nav.channel.nml\n", + "pyNeuroML >>> INFO - Loading LEMS file: LEMS_olm_example_sim.xml and running with jNeuroML_NEURON\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx2G -Djava.awt.headless=true -jar \"/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar\" \"LEMS_olm_example_sim.xml\" -neuron -run -compile -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed. Output: \n", + " jNeuroML >> jNeuroML v0.12.0\n", + " jNeuroML >> (INFO) Reading from: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_olm_example_sim.xml\n", + " jNeuroML >> (INFO) Creating NeuronWriter to output files to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples\n", + " jNeuroML >> (INFO) Adding simulation Component(id=olm_example_sim type=Simulation) of network/component: single_olm_cell_network (Type: network)\n", + " jNeuroML >> (INFO) Adding population: pop0\n", + " jNeuroML >> (INFO) -- Writing to hoc: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm.hoc\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/leak_chan.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/leak_chan.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/HCNolm.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/HCNolm.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Kdrfast.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Kdrfast.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/KvAolm.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/KvAolm.mod exists and is identical\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Nav.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/Nav.mod exists and is identical\n", + " jNeuroML >> (INFO) Adding projections/connections...\n", + " jNeuroML >> (INFO) -- Writing to mod: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_olm.mod\n", + " jNeuroML >> (INFO) File /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/pg_olm.mod exists and is identical\n", + " jNeuroML >> (INFO) Trying to compile mods in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples\n", + " jNeuroML >> (INFO) Going to compile the mod files in: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples, forcing recompile: false\n", + " jNeuroML >> (INFO) Parent dir: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples\n", + " jNeuroML >> (INFO) Assuming *nix environment...\n", + " jNeuroML >> (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.la\n", + " jNeuroML >> (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so\n", + " jNeuroML >> (INFO) Name of file to be created: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so\n", + " jNeuroML >> (INFO) commandToExecute: /usr/bin/nrnivmodl\n", + " jNeuroML >> (INFO) Found previously compiled file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so\n", + " jNeuroML >> (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/libnrnmech.so\n", + " jNeuroML >> (INFO) Going to check if mods in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so\n", + " jNeuroML >> (INFO) Not being asked to recompile, and no mod files exist in /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples which are newer than /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/x86_64/.libs/libnrnmech.so\n", + " jNeuroML >> (INFO) Success in compiling mods: true\n", + " jNeuroML >> (INFO) Have successfully executed command: python /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_olm_example_sim_nrn.py\n", + " jNeuroML >> (INFO) NRN Output >>> \n", + " jNeuroML >> (INFO) NRN Output >>> Starting simulation in NEURON of 600ms generated from NeuroML2 model...\n", + " jNeuroML >> (INFO) NRN Output >>> \n", + " jNeuroML >> (INFO) NRN Output >>> Population pop0 contains 1 instance(s) of component: olm of type: cell\n", + " jNeuroML >> (INFO) NRN Output >>> \t1 \n", + " jNeuroML >> (INFO) NRN Output >>> Setting up the network to simulate took 0.006119 seconds\n", + " jNeuroML >> (INFO) NRN Output >>> Running a simulation of 600.0ms (dt = 0.01ms; seed=123)\n", + " jNeuroML >> (INFO) NRN Output >>> Finished NEURON simulation in 0.424608 seconds (0.007077 mins)...\n", + " jNeuroML >> (INFO) NRN Output >>> Saving results at t=599.9999999995268...\n", + " jNeuroML >> (INFO) NRN Output >>> Saved data to: time.dat\n", + " jNeuroML >> (INFO) NRN Output >>> Saved data to: olm_example_sim.dat\n", + " jNeuroML >> (INFO) NRN Output >>> Finished saving results in 0.455872 seconds\n", + " jNeuroML >> (INFO) NRN Output >>> Done\n", + " jNeuroML >> (INFO) Exit value for running NEURON: 0\n", + " jNeuroML >> \n", + "pyNeuroML >>> INFO - Generating plot: Membrane potential (soma seg 0)\n", + "/home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/.venv/lib64/python3.10/site-packages/pyneuroml/plot/Plot.py:186: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n", + " plt.plot(\n", + "pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg0_soma0-v.png of plot: Membrane potential (soma seg 0)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Saved image to olm_example_sim_seg0_soma0-v.png of plot: Membrane potential (soma seg 0)\n", + "pyNeuroML >>> INFO - Generating plot: Membrane potential (soma seg 1)\n", + "pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg1_soma0-v.png of plot: Membrane potential (soma seg 1)\n", + "pyNeuroML >>> INFO - Saved image to olm_example_sim_seg1_soma0-v.png of plot: Membrane potential (soma seg 1)\n", + "pyNeuroML >>> INFO - Generating plot: Membrane potential (axon seg 0)\n", + "pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg0_axon0-v.png of plot: Membrane potential (axon seg 0)\n", + "pyNeuroML >>> INFO - Saved image to olm_example_sim_seg0_axon0-v.png of plot: Membrane potential (axon seg 0)\n", + "pyNeuroML >>> INFO - Generating plot: Membrane potential (axon seg 1)\n", + "pyNeuroML >>> INFO - Saving image to /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/olm_example_sim_seg1_axon0-v.png of plot: Membrane potential (axon seg 1)\n", + "pyNeuroML >>> INFO - Saved image to olm_example_sim_seg1_axon0-v.png of plot: Membrane potential (axon seg 1)\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAG4CAYAAACZypnDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAABf2klEQVR4nO3deVxU5f4H8M+ZGRhAFkEBQXFBRdwKFzCzVFJbpK5lgJrmkl0pu2mau5nSoqWpqfdaaoVtWoqW/czKMndN3LVUNJREwBVkZBtg5vz+gBkZZ8DhMHBm8PN+vebqnHOeme85V+Pj8zznOYIoiiKIiIiIyGYUchdAREREVNcwYBERERHZGAMWERERkY0xYBERERHZGAMWERERkY0xYBERERHZGAMWERERkY2p5C7gXqTX65GRkQEPDw8IgiB3OURERGQFURRx69YtBAYGQqGovI+KAUsGGRkZCAoKkrsMIiIikiAtLQ1NmjSp9BgGLBl4eHgAKP0/yNPTU+ZqiIiIyBoajQZBQUHGn+OVYcCSgWFY0NPTkwGLiIjIwVgzvYeT3ImIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLyMHp9CImrjuGv6/myl0KERGVYcAicnBZeUXYeCQdc7eclrsUIiIqw4BF5OAKinQASnuyiIjIPjBgETm4vKISAICTUpC5EiIiMmDAInJwRSV6uUsgIqI7MGAROTi9WDo0WKTjECERkb1gwCJycIapV8XsySIishsMWEQOrzRhlegZsIiI7AUDFpGDM/RgcYiQiMh+MGAROTiRQ4RERHanzgQsrVaLqVOnIjAwEK6urujWrRt+/fVXq9qmp6cjNjYW9evXh6enJwYMGIDz589X2mbPnj0QBAGCIOD69eu2OAUiSQyT3A2/EhGR/OpMwBo5ciQWLVqEoUOHYsmSJVAqlejfvz/27NlTabvc3FxERkZi586dmDFjBuLj43H06FH06tULN27csNhGr9fj1VdfRb169WriVIiqxJCrGLCIiOxHnQhYSUlJ+OabbzBv3jwsWLAAY8aMwe+//45mzZphypQplbZdvnw5zp07h82bN2PKlCmYMGECtm7diszMTCxcuNBim5UrVyItLQ0vvvhiTZwOUZWIZcGKK7kTEdmPOhGwEhMToVQqMWbMGOM2FxcXjB49Gvv370daWlqlbcPDwxEeHm7cFhoaij59+mDdunVmx2dlZeGNN97AW2+9hfr169v0PIikMMQqdmAREdmPOhGwjh49ipCQEHh6eppsj4iIAAAcO3bMYju9Xo8TJ06ga9euZvsiIiKQkpKCW7dumWyfNWsWGjVqhLi4OKvr02q10Gg0Ji8iWzEMDeqYsIiI7EadCFiZmZkICAgw227YlpGRYbFdVlYWtFqt1W1PnDiBFStWYNGiRVAqlVbXN2/ePHh5eRlfQUFBVrcluhtDruIQIRGR/agTAaugoABqtdpsu4uLi3F/Re0AWN123LhxeOKJJ/Doo49Wqb7p06cjJyfH+KpsyJKoqox3ETJgERHZDZXcBdiCq6srtFqt2fbCwkLj/oraAbCq7bfffot9+/bhzz//rHJ9arXaYogjsgVDrOIQIRGR/agTASsgIADp6elm2zMzMwEAgYGBFtv5+PhArVYbj6us7eTJkxETEwNnZ2ekpqYCAG7evAkASEtLQ1FRUYXfQ1STbt9FKHMhRERkVCcCVlhYGLZv3w6NRmMy0f3AgQPG/ZYoFAp07NgRhw4dMtt34MABBAcHw8PDA0BpiFqzZg3WrFljdmznzp1x//33VziZnqgmGTquRPZgERHZjToxBys6Oho6nQ4rV640btNqtUhISEC3bt2Mk8ovXryIM2fOmLU9ePCgSchKTk7G77//jpiYGOO27777zuw1aNAgAMAXX3yBxYsX1+QpElXIMPWKQ4RERPajTvRgdevWDTExMZg+fTquXr2KVq1a4fPPP0dqaio+/fRT43HDhw/Hzp07Tf6lP3bsWKxatQpRUVGYNGkSnJycsGjRIvj7++P11183Hvf000+bfa+hx+qJJ55Aw4YNa+z8iCqj50KjRER2p04ELKC0F2nWrFn48ssvkZ2djfvuuw+bN29Gz549K23n4eGBHTt2YMKECXjnnXeg1+vRu3dvLF68GL6+vrVUPZF0t4cI5a2DiIhuE0RO3Kh1Go0GXl5eyMnJMVsclaiqfjqZiZe/PgJXJyVOv/243OUQEdVZVfn5XSfmYBHdy7hMAxGR/WHAInJwXGiUiMj+MGAROThDx5WePVhERHaDAYvIwRl7sJiviIjsBgMWERERkY0xYBE5OA4NEhHZHwYsIgdXPl9xojsRkX1gwCJycOUzVbGeT3wmIrIHDFhEDq78WsHMV0RE9oEBi8jBlR8iLGHCIiKyCwxYRA5OxO2ExQc+ExHZBwYsIgenN+nBYsAiIrIHDFhEDq78ECF7sIiI7AMDFpGDK78OFnuwiIjsAwMWkYMrfxehTseARURkDxiwiBxc+UjFuwiJiOwDAxaRgyu/ejvnYBER2QcGLCIHZ9qDxYBFRGQPGLCIHJyedxESEdkdBiwiByfyLkIiIrvDgEXk4EzXweIkdyIie8CAReTgTB+VI2MhRERkxIBF5OD0fNgzEZHdYcAicnB8VA4Rkf1hwCJycHxUDhGR/WHAIqpD+KgcIiL7wIBF5OD0ehFOSgEAe7CIiOwFAxaRgxMBOClL/ypzDhYRkX1gwCJycHpRhEph6MHiXYRERPaAAYvIwelF9mAREdkbBiwiRyeKxoDFOVhERPaBAYvIwelFQFk2RMgeLCIi+8CAReTgRIhQKACVQmAPFhGRnWDAInJwehEQIECpEKDjwwiJiOwCAxaRgxNFQCGwB4uIyJ4wYBE5OFEUIQilPVjlH5tDRETyYcAicnAiAEEAVEoFe7CIiOwEAxaRg9PrRQhA2RwsBiwiInvAgEXk4EQACkHgHCwiIjvCgEXk4PSiCEEo68FiwCIisgsMWEQOrvQuQvZgERHZEwYsIgcnlt05qFAI0PFhz0REdqHOBCytVoupU6ciMDAQrq6u6NatG3799Ver2qanpyM2Nhb169eHp6cnBgwYgPPnz5sck5aWhvj4eERERMDb2xsNGzZE79698dtvv9XE6RBZjXOwiIjsT50JWCNHjsSiRYswdOhQLFmyBEqlEv3798eePXsqbZebm4vIyEjs3LkTM2bMQHx8PI4ePYpevXrhxo0bxuM2bdqE999/H61atcI777yDWbNm4datW+jXrx8SEhJq+vSIKnR7DpaCc7CIiOyEIIqOvzJhUlISunXrhgULFmDSpEkAgMLCQnTo0AF+fn7Yt29fhW3nz5+PqVOnIikpCeHh4QCAM2fOoEOHDpgyZQrmzp0LAPjrr7/g7++Phg0bGttqtVqEhYUhNzcXaWlpVter0Wjg5eWFnJwceHp6SjllIqMZ353EyUs5AICOTbww95mOMldERFQ3VeXnd53owUpMTIRSqcSYMWOM21xcXDB69Gjs37+/0vCTmJiI8PBwY7gCgNDQUPTp0wfr1q0zbmvfvr1JuAIAtVqN/v3749KlS7h165YNz4jIeoZH5XAdLCIi+1EnAtbRo0cREhJiliYjIiIAAMeOHbPYTq/X48SJE+jatavZvoiICKSkpNw1OF2+fBlubm5wc3Or8BitVguNRmPyIrIVURQBzsEiIrIrdSJgZWZmIiAgwGy7YVtGRobFdllZWdBqtZLaAsDff/+NjRs34tlnn4VSqazwuHnz5sHLy8v4CgoKqvR8iKrCpAeLdxESEdmFageswsJCaLVaW9QiWUFBAdRqtdl2FxcX4/6K2gGQ1DY/Px8xMTFwdXXFe++9V2l906dPR05OjvFVlflaRHejF0sflaNSCuAIIRGRfVBVtcGOHTuwadMm7N27F6dOnTIGEDc3N7Rt2xYPPvggnn76afTu3dvWtVbI1dXVYsgrLCw07q+oHYAqt9XpdBg8eDBOnTqFn376CYGBgZXWp1arLYY4IlswLNNQehche7CIiOyBVQGruLgYK1aswKJFi5CamgofHx907twZw4YNg7e3N0RRRHZ2Ni5cuICvvvoKS5cuRbNmzfD6668jLi4OTk5ONXoSAQEBSE9PN9uemZkJABUGIB8fH6jVauNx1rb997//jc2bN+Prr7/GI488Up3SiarNsEyDSiGghF1YRER2waqA1apVKxQVFWHEiBGIjY1F586dKz3+8OHDWL9+PebOnYsPPvgAqamptqi1QmFhYdi+fTs0Go3JRPcDBw4Y91uiUCjQsWNHHDp0yGzfgQMHEBwcDA8PD5PtkydPRkJCAj788EMMGTLEdidBJJUICILAZxESEdkRq+ZgzZgxA6mpqXjvvffuGq4AoEuXLnjvvfeQmpqK6dOnV7vIu4mOjoZOp8PKlSuN27RaLRISEtCtWzfjpPKLFy/izJkzZm0PHjxoErKSk5Px+++/IyYmxuTYBQsW4IMPPsCMGTMwfvz4GjwjIusZ52DxLkIiIrtRJxYaBYDY2Fh89913mDBhAlq1aoXPP/8cSUlJ2LZtG3r27AkA6N27N3bu3Inyp3zr1i106tQJt27dwqRJk+Dk5IRFixZBp9Ph2LFj8PX1BQB89913GDhwIFq3bo0333zT7Pv79esHf39/q2rlQqNkS+O/OYqrGi183J2Rk1+Mr17sJndJRER1UlV+fls9yT06OhrPP/88+vfvX+NzqqT44osvMGvWLHz55ZfIzs7Gfffdh82bNxvDVUU8PDywY8cOTJgwAe+88w70ej169+6NxYsXG8MVABw/fhwAcO7cOTz//PNmn7N9+3arAxaRLelLl8Eq68HiJHciIntgdQ+Wq6srioqK4OXlhZiYGAwdOvSu4YUsYw8W2dJ/1hzBzfxi+HmqkZaVj/UvPSh3SUREdVKNPCrn2rVr+OyzzxAeHo7PPvsMkZGRaNq0KaZNm4YTJ05Uu2gikkY06cGqEyP+REQOz+qA5e7ujhEjRuCXX35BRkYGPvzwQzRu3Bjz589Hp06d0LFjR7z//vu4ePFiTdZLRHcQIZbdRajgXYRERHZC0kruvr6+ePXVV7F//36cP38eb731FoDSFcuDg4PRs2dPkzv6iKjm6PW4fRch18EiIrIL1X5UTvPmzTFz5kycPHkSx44dw1NPPYU9e/bg5ZdftkV9RHQXIsRyzyJkwCIisgdVflSOJZmZmVi7di3WrFmDI0eOAAC6du1qi48morvQi6WPyuFdhERE9kNywLp58yYSExOxZs0a7N69GzqdDi1btsSbb76JYcOGoVWrVrask4gqIJY9KkepFMAOLCIi+1ClgFVYWIgffvgBa9aswS+//AKtVgtfX1+8/PLLGDZsGCIiImqqTiKqgCgCCgV7sIiI7InVAWv48OHYtGkTcnNz4ebmhmeffRZDhw7Fo48+CqVSWZM1ElEl9KIIJcruIuQkdyIiu2B1wFq7di369euHoUOH4plnnoGbm1tN1kVEVhJROgdLKXAdLCIie2F1wMrIyDB5dAwR2Qfjo3KUvIuQiMheWLVMQ1pamuRwlZaWJqkdEVlHFMXSHiyu5E5EZDesClitWrXCCy+8gKSkJKs/eN++fRg+fDhat24tuTgiujtRBFD2qBz2YBER2Qerhgh3796NN954Aw888ACaNWuGRx55BJ07d0aLFi3g7e0NURSRnZ2NCxcu4NChQ/j999+Rnp6OyMhI7Nq1q6bPgeieVrrQqKEHi3cREhHZA6sCVkREBLZu3Ypjx44hISEBmzZtQkJCAgBAEAQApcMUABAUFISnn34aL7zwAsLCwmqmaiIyKv+oHPZgERHZhyqtgxUWFoYlS5ZgyZIlyMjIwJkzZ3Djxg0AQIMGDRAaGorAwMAaKZSILLv9qBwF52AREdkJySu5BwYGMkwR2YHSuwhLFxoVRUCvF6FQCHKXRUR0T6v2w56JSGZlyzQoy0IVe7GIiOTHgEXk4PSiCAECVMrSgMV5WERE8mPAInJwpSu53+7B0okMWEREcmPAInJw+rKFRlWGgMXnERIRyY4Bi8jBGR6VoxAMc7C4FhYRkdwYsIgcnSiW3kXIOVhERHbDqmUa3nrrrSp/sCAImDVrVpXbEVHV6I13EZb+e4l3ERIRyc+qgDVnzpwqfzADFlHtMCw0apyDxYBFRCQ7qwKWnnM6iOxW6aNyBK6DRURkRzgHi8jBGZZpuN2DxX8QERHJjQGLyMGJZZPc2YNFRGQ/JD+L8MSJE1i2bBmOHDmCnJwcs2FEQRCQkpJS7QKJqHJi2SR3lWGSO9fBIiKSnaQerB07diAiIgKbN29GYGAgzp8/j+DgYAQGBuKff/6Bu7s7evbsaetaicgCw6NylJzkTkRkNyQFrDfffBPBwcFITk5GQkICAGDGjBnYs2cP9u3bh0uXLiE2NtamhRKRZcY5WEoOERIR2QtJAevIkSMYPXo0PD09oVQqAQA6nQ4A0K1bN8TFxXGJBqJaohfFsnWw2INFRGQvJAUslUoFDw8PAED9+vXh5OSEq1evGvcHBwfj1KlTtqmQiConwvRZhAxYRESykxSwWrVqhXPnzgEoncweGhqK7777zrj/xx9/RKNGjWxTIRFVSi+KQLlnETJgERHJT1LA6t+/P9auXYuSkhIAwMSJE7Fx40a0bt0arVu3xg8//IC4uDibFkpElpXOwRLKzcHiOlhERHKTtEzDrFmzMH78eOP8qxEjRkCpVGLDhg1QKpWYOXMmRo4cacs6iagCpXcRcg4WEZE9kRSwnJyc0KBBA5Ntw4YNw7Bhw2xSFBFZT683zMHiw56JiOwFV3InqgMUvIuQiMiuWNWDFRkZCYVCgV9++QUqlQqPPPLIXdsIgoBt27ZVu0Aiqpy+bCl3FR+VQ0RkN6wKWKIomjwKR6/XQyi7Y6myNkRU80Txzh4sTnInIpKbVQFrx44dlb4nIvkYHpVj7MHiswiJiGQnaQ7Wrl27cO3atQr3X79+Hbt27ZJcFBFZTwS4kjsRkZ2RFLAiIyPx66+/Vrh/27ZtiIyMlFyUFFqtFlOnTkVgYCBcXV3RrVu3SmssLz09HbGxsahfvz48PT0xYMAAnD9/3uKxn376Kdq2bQsXFxe0bt0ay5Yts+VpEFWZKIpQCKXzHpUKgXOwiIjsgKSAdbf5VVqt1rhGVm0ZOXIkFi1ahKFDh2LJkiVQKpXo378/9uzZU2m73NxcREZGYufOnZgxYwbi4+Nx9OhR9OrVCzdu3DA5dsWKFXjxxRfRvn17LFu2DN27d8e4cePw/vvv1+SpEVWqdI57ae+VUiGwB4uIyA5YvQ7WxYsXkZqaanx/5swZi8OAN2/exIoVK9CsWTObFGiNpKQkfPPNN1iwYAEmTZoEABg+fDg6dOiAKVOmYN++fRW2Xb58Oc6dO4ekpCSEh4cDAJ544gl06NABCxcuxNy5cwEABQUFmDlzJqKiopCYmAgA+Pe//w29Xo+3334bY8aMgbe3dw2fKZE5vSgaH5OjFNiDRURkD6zuwUpISEDv3r0RGRkJQRDw7rvvIjIy0uz19NNPIykpCdOnT6/Juk0kJiZCqVRizJgxxm0uLi4YPXo09u/fj7S0tErbhoeHG8MVAISGhqJPnz5Yt26dcdv27dtx48YNjB071qT9K6+8gry8PPz44482PCMi6+lLV2kAAKgUAvQMWEREsrO6Bys2NhYdOnSAKIqIjY3FuHHj8PDDD5scIwgC6tWrh7CwMPj7+9u82IocPXoUISEh8PT0NNkeEREBADh27BiCgoLM2un1epw4cQIvvPCC2b6IiAhs3boVt27dgoeHB44ePQoA6Nq1q8lxXbp0gUKhwNGjRytcyV6r1UKr1RrfazSaqp0gUSUMc7AAQKlkDxYRkT2wOmC1bdsWbdu2BVDam9WzZ0+0aNGixgqriszMTAQEBJhtN2zLyMiw2C4rKwtarfaubdu0aYPMzEwolUr4+fmZHOfs7IwGDRpU+B0AMG/ePMTHx1t9PkRVUboOVmnCUikEroNFRGQHJE1yHzFihN2EK6B0fpRarTbb7uLiYtxfUTsAVrUtKCiAs7Ozxc9xcXGp8DsAYPr06cjJyTG+KhuyJKoqfbmbTngXIRGRfZD0sGcAOH36NBISEnD+/HlkZ2eb3VlYm4/KcXV1NRmCMygsLDTur6gdAKvaurq6oqioyOLnFBYWVvgdQGmAsxTiiGxBRPkeLAXvIiQisgOSAtaXX36JUaNGwcnJCW3atLF491xtPionICAA6enpZtszMzMBAIGBgRbb+fj4QK1WG4+rrG1AQAB0Oh2uXr1qMkxYVFSEGzduVPgdRDVNX34OFnuwiIjsgqSANWfOHHTq1Ak//fQTGjZsaOuaqiwsLAzbt2+HRqMxmeh+4MAB435LFAoFOnbsiEOHDpntO3DgAIKDg+Hh4WHyGYcOHUL//v2Nxx06dAh6vb7C7yCqafpy62CpuA4WEZFdkDQHKyMjAy+88IJdhCsAiI6Ohk6nw8qVK43btFotEhIS0K1bN+MdhBcvXsSZM2fM2h48eNAkZCUnJ+P3339HTEyMcdsjjzwCHx8ffPTRRybtP/roI7i5uSEqKqomTo3o7soe9gyU9WDxWYRERLKT1IN13333VXrXXG3r1q0bYmJiMH36dFy9ehWtWrXC559/jtTUVHz66afG44YPH46dO3eaDF+OHTsWq1atQlRUFCZNmgQnJycsWrQI/v7+eP31143Hubq64u2338Yrr7yCmJgYPPbYY9i9eze++uorvPvuu/Dx8anVcyYy0IuiyUruJbyLkIhIdpIC1qJFixATE4MnnngCDz74oK1rkuSLL77ArFmz8OWXXyI7Oxv33XcfNm/ejJ49e1bazsPDAzt27MCECRPwzjvvQK/Xo3fv3li8eDF8fX1Njh07diycnJywcOFC/PDDDwgKCsLixYsxfvz4mjw1okqVBqzS3zspFShmDxYRkewEUcJs9H/96184d+4czp49i3bt2qFp06Zmzx4UBAGbNm2yWaF1iUajgZeXF3JycswWRyWqqhbTf8TcZzpiSERTDFy+F8G+7vgg5n65yyIiqnOq8vNbUg/WiRMnIAgCmjZtitzcXJw6dcrsGMOQBRHVHFEUyxYaLX3vrFKgqIRDhEREcpMUsMo/9JmI5GPofxZQmrCcVUoGLCIiOyDpLkIisg+G8X1Dh7GzUkCxjgGLiEhukgOWTqfDN998g7i4ODzzzDM4efIkACAnJwcbN27ElStXbFYkEVlmeEyOYSV3Z5UCRQxYRESykxSwbt68iR49euC5557D2rVr8cMPP+DatWsAAHd3d4wbNw5LliyxaaFEZM4QsG73YHEOFhGRPZAUsKZNm4a//voLv/zyC86fP2+yrpRSqUR0dDS2bNlisyKJyDLDXz1DD5aTkj1YRET2QFLA+v777/Hqq6+iX79+Fu8WDAkJ4UR4olpgnOTOuwiJiOyKpICVk5ODFi1aVLi/uLgYJSUlkosiIuvcHiK8PQeLk9yJiOQnKWC1bNkSR44cqXD/1q1b0a5dO8lFEZF1DIPzCs7BIiKyK5IC1osvvojPPvsM3377rXH+lSAI0Gq1mDlzJn7++WfExcXZtFAiMmfswUK5uwgZsIiIZCdpodHx48fjr7/+wpAhQ1C/fn0AwHPPPYcbN26gpKQEcXFxGD16tC3rJCILbk9yL/3VWalAEZ9FSEQkO0kBSxAErFq1CiNGjEBiYiLOnTsHvV6Pli1bIjY29q4PWCYi2xDvmIPlpFKgqEQnZ0lERASJAcvgoYcewkMPPWSrWoioivR33kWoVKCYPVhERLKTNAdLqVRizZo1Fe7/9ttvoVQqJRdFRNYRuZI7EZFdkhSwyi8saolOp7O4PhYR2ZbewhwsnV6ETs9eLCIiOUl+FmFFAUqj0eCXX35Bw4YNJRdFRNYR73xUjqr0rzTXwiIikpfVASs+Ph5KpRJKpRKCIGDYsGHG9+Vf3t7e+PLLLzF48OCarJuIcHsdrPILjQKAlks1EBHJyupJ7hERERg7dixEUcTy5cvRr18/hISEmBwjCALq1auHLl26YODAgTYvlohM6e+Yg+WkLA1YXAuLiEheVgesJ554Ak888QQAIC8vDy+99BK6detWY4UR0d0Z7yIse88hQiIi+yBpmYaEhARb10FEEpjdRcgeLCIiuyB5krtGo0F8fDwiIiLg7+8Pf39/RERE4K233oJGo7FljURUAbOV3FWlv2EPFhGRvCQFrIyMDHTq1Anx8fHIzc1Fjx490KNHD+Tl5WHOnDno3LkzMjMzbV0rEd3BMAcLxmUaStef4yR3IiJ5SRoinDp1Ki5fvozNmzejf//+Jvt++uknxMTEYNq0afj8889tUiQRWXa7B8v0LkIuNkpEJC9JPVg///wzXnvtNbNwBZROhh83bhy2bNlS7eKIqHLmdxGWDRGyB4uISFaSAlZeXh78/f0r3N+oUSPk5eVJLoqIrGP2LEL2YBER2QVJAatdu3ZYu3YtioqKzPYVFxdj7dq1aNeuXbWLI6K7MfRglb7jMg1ERPZB8hysQYMGGRcfNSw4mpycjI8//hgnTpzAt99+a9NCicjc7R4sLtNARGRPJAWsmJgY5OXlYdq0aXjppZeM/3EXRRF+fn747LPPEB0dbdNCicicYQ7WnQuN8i5CIiJ5SQpYADBy5EgMGzYMBw8exMWLFwEAzZo1Q9euXaFSSf5YIqoCs7sI2YNFRGQXqpWEVCoVunfvju7du9uqHiKqgjvvIlQpFVAInORORCQ3yQFLq9Vi1apV2LJlC1JTUwEAzZs3R//+/fHiiy/CxcXFVjUSUQXEO+4iBEqHCdmDRUQkL0l3EV66dAlhYWEYN24cjh8/Dl9fX/j6+uL48eMYN24cwsLCcOnSJVvXSkR3sBiwlAxYRERykxSwXnnlFfzzzz9Yt24d0tPTsXPnTuzcuRPp6en49ttvcfHiRbzyyiu2rpWI7nDnECHAHiwiInsgaYhw27ZtmDBhgsU7BWNiYnDkyBEsW7as2sURUeWMdxHe2YPFOVhERLKS1IPl4eEBPz+/Cvc3atQIHh4ekosiIuuUjRBCwB09WAxYRESykhSwRo0ahdWrVyM/P99sX25uLhISEjB69OhqF0dEldOXrTSqLPc3mUOERETykzREGBYWhh9//BGhoaEYMWIEWrVqBQA4d+4cvvjiC/j4+OC+++7Dxo0bTdoNHDiw+hUTkZFOzzlYRET2SFLAGjx4sPH37777rtn+S5cuYciQIRANtzih9FEeOp1OytcRUQV0oqEHq1zA4l2ERESykxSwtm/fbus6iEgCfVmOMuvB4hwsIiJZSQpYvXr1snUdRCSBxR4slZI9WEREMpM0yZ2I7MPtSe4cIiQisicMWEQOzNIkdzWHCImIZFcnAtbNmzcxZswY+Pr6ol69eoiMjMSRI0esbn/69Gk8/vjjcHd3h4+PD55//nlcu3bN5JgzZ85gypQpCAsLg4eHBwICAhAVFYVDhw7Z+nSIrGZ5iFABLXuwiIhk5fABS6/XIyoqCmvWrMF//vMfzJ8/H1evXkXv3r1x7ty5u7a/dOkSevbsib///htz587FpEmT8OOPP6Jfv34oKioyHvfJJ59g1apV6Nq1KxYuXIiJEyciOTkZDzzwAH777beaPEWiChmHCAUOERIR2RNJk9ztSWJiIvbt24f169cbH90TGxuLkJAQzJ49G2vWrKm0/dy5c5GXl4fDhw+jadOmAICIiAj069cPq1evxpgxYwAAQ4YMwZw5c+Du7m5s+8ILL6Bt27aYM2cO+vbtW0NnSFQxQw+Wotw/lZxUAgMWEZHMbNKDlZOTI9saV4mJifD39zdZxNTX1xexsbHYtGkTtFptpe03bNiAJ5980hiuAKBv374ICQnBunXrjNu6dOliEq4AoEGDBnj44Ydx+vRpG50NUdXoLE5yV6KYc7CIiGQlOWAdOnQIjz/+ONzc3NCgQQPs3LkTAHD9+nUMGDAAO3bssFWNlTp69Cg6d+4MhcL0VCIiIpCfn4+zZ89W2DY9PR1Xr15F165dzfZFRETg6NGjd/3+y5cvo2HDhpUeo9VqodFoTF5EtmB42DPXwSIisi+SAta+ffvw0EMP4dy5cxg2bBj0+tv/MW/YsCFycnKwYsUKmxVZmczMTAQEBJhtN2zLyMiotG35Y+9sn5WVVWkP2O7du7F//34MGjSo0hrnzZsHLy8v4ysoKKjS44msZchRd05y5xAhEZG8JAWsGTNmoG3btjh16hTmzp1rtj8yMhIHDhyo8ufq9XoUFhZa9TI8hqegoABqtdrss1xcXIz7K2LYJ6X91atX8dxzz6FFixaYMmVKpec1ffp05OTkGF9paWmVHk9kLUuT3NUMWEREspM0yf3gwYOYN28e1Go1cnNzzfY3btwYly9frvLn7tq1C5GRkVYde/r0aYSGhsLV1dViL1NhYSEAwNXVtcLPMOyravu8vDw8+eSTuHXrFvbs2WM2N+tOarXaYogjqq7bk9x5FyERkT2RFLCcnJxMhgXvlJ6eftfQYUloaCgSEhKsOtYwrBcQEGAc6ivPsC0wMPCun1FRex8fH7NgVFRUhIEDB+LEiRP45Zdf0KFDB6vqJaoJOr1oMjwIlK2DxTlYRESykhSwHnjgASQmJuK1114z25eXl4eEhARJzyts1KgRRo4cWaU2YWFh2L17N/R6vclE9wMHDsDNzQ0hISEVtm3cuDF8fX0tLhaalJSEsLAwk216vR7Dhw/Htm3bsG7dOj6TkWSnF0WT4UHg9hwsURQh3LGPiIhqh6Q5WPHx8Th06BCioqLw008/AQCOHz+OTz75BF26dMG1a9cwa9YsmxZakejoaFy5cgUbN240brt+/TrWr1+Pp556yqQHKiUlBSkpKSbtn332WWzevNlkXtS2bdtw9uxZxMTEmBz76quv4ttvv8Xy5ctNloUgkotOL+KOG2jhrCzdUKwTZaiIiIgAiT1Y3bp1w5YtW/Dyyy9j+PDhAIDXX38dANCyZUts2bIF9913n+2qrER0dDQeeOABjBo1CqdOnULDhg2xfPly6HQ6xMfHmxzbp08fAEBqaqpx24wZM7B+/XpERkZi/PjxyM3NxYIFC9CxY0eMGjXKeNyHH36I5cuXo3v37nBzc8NXX31l8tnPPPMM6tWrV3MnSmSBTi+aLNEAlPZgAUCRTm/8PRER1S7JK7k/8sgjSE5OxrFjx3Du3Dno9Xq0bNkSXbp0qdVhCaVSiS1btmDy5MlYunQpCgoKEB4ejtWrV6NNmzZ3bR8UFISdO3di4sSJmDZtGpydnREVFYWFCxea9H4dO3YMALB//37s37/f7HMuXLjAgEW1rqIhQgClE915bwURkSwE0bDeAdUajUYDLy8v5OTkwNPTU+5yyIF9tCMFH+9MwfHZjxq3bT9zFaNWH8Qf0/ugkZeLjNUREdUtVfn5Xa1nEZ46dQrnz59HdnY2LOU0w/AhEdUMvWj5LkIAXKqBiEhGkgJWSkoKhg0bhqSkJIvBCgAEQWDAIqphd5uDRURE8pAUsOLi4nDy5El8+OGHePjhh+Ht7W3ruojICqXrYJluM9xFyB4sIiL5SApYe/fuxYwZM/Dqq6/auh4iqoJKJ7mzB4uISDaS7uFu2LAhvLy8bF0LEVVR6TpYnINFRGRvJAWsl156CV999RV0Op2t6yGiKtBZmuTOIUIiItlJGiIMCQmBTqfD/fffjxdeeAFBQUFQKpVmx3G1c6KaVaITobojYKmNQ4T8BxARkVwkBaxBgwYZfz9p0iSLxwiCwB4uohpWotPD6Y5Z7hwiJCKSn6SAtX37dlvXQUQSFOvFCgOWlgGLiEg2kgJWr169bF0HEUlQXKKHSsk5WERE9oZPgiVyYCV6EU4K07/GKqUCCoHLNBARyUnyo3IuX76MTz/9FEeOHEFOTg70etP/mAuCgG3btlW7QCKqWLFODyeV+cPVnZQK9mAREclIUsA6ceIEevfujYKCArRp0wYnT55Eu3btcPPmTaSnp6Nly5YICgqyda1EdIfSuwjNO6KdVQxYRERykjREOG3aNLi7uyM5ORm//fYbRFHEkiVLkJaWhm+//RbZ2dl47733bF0rEd2hWKeHk9K8B0utUqCYQ4RERLKRFLD27t2LuLg4NG3aFIqyfz0bhghjYmIwdOhQTJ482XZVEpFFlu4iBEonurMHi4hIPpICll6vh7+/PwCgfv36UCqVyMrKMu7v2LEjDh8+bJsKiahCJTo9VJYClkoBLXuwiIhkIylgtWjRAhcuXCj9AIUCLVq0wG+//Wbcv2/fPtSvX98mBRJRxYp1ejgpzIcIOQeLiEhekgLWo48+ivXr1xvfv/zyy/jkk0/Qt29f9OnTB59//jmee+45mxVJRJYV6yoYImTAIiKSlaS7CGfOnIkhQ4aguLgYTk5OeO2115CXl4cNGzZAqVRi1qxZmDFjhq1rJaI7lOjNFxoFOAeLiEhuVQ5YoihCqVSiffv2cHJyAlC65tUbb7yBN954w+YFElHFikss92CplAro9KIMFRERESBhiLCoqAg+Pj5YunRpTdRDRFVQrLe8TINKIaCYAYuISDZVDlhqtRqNGjWCWq2uiXqIqApKdKLFuwiVCgE6PYcIiYjkImmS+8iRI/HFF1+gqKjI1vUQURWULjRq/tfYSalAsY49WEREcpE0yb1jx474/vvv0b59e4wcORLNmzeHq6ur2XEDBw6sdoFEVLHCYh1cnCrqwWLAIiKSi6SANWTIEOPvZ82aZfEYQRCg0+mkVUVEViks1sNFpTTb7qQUoOVdhEREspEUsLZv327rOoioikRRRGGJDi5O5gFLqVCgRFcsQ1VERARIDFi9evWydR1EVEVFOj1EERaHCFUKASUcIiQiko2kgGWg0+lw+PBhpKamAgCaN2+OLl26QKk0/xc1EdlWYXHpEKClHiyVQkAJn0VIRCQbyQFr9erVmD59Oq5evQpRLP2XsiAI8PX1xdy5c/HCCy/YrEgiMqctLp3jaLEHS8lJ7kREcpIUsFasWIGXX34ZYWFhmDNnDkJCQgAAycnJWLFiBf7973+jqKgIL730kk2LJaLbjD1YFia5qxRcpoGISE6SAtb777+Phx9+GL/99pvxcTkAEBkZidGjR+ORRx7B/PnzGbCIalBhSWkPltriJHf2YBERyUnSQqOXL19GbGysSbgycHJywuDBg3HlypVqF0dEFSusZIjQSSmgmCu5ExHJRlLA6tSpE86ePVvh/rNnzyIsLExqTURkhcomuSsVfNgzEZGcJA0RLlu2DFFRUQgODsaYMWOMq7gXFBTg448/xrp167BlyxabFkpEpm73YFV0FyEDFhGRXKwKWPfdd5/ZNqVSiYkTJ2LKlCkIDAwEAGRkZKCkpAQBAQEYOXIkjh8/bttqicgoV1sCAHB3Nv9rrFIKKOEQIRGRbKwKWD4+PhAEwWRbgwYN0Lp1a5NtzZs3t1lhRFS53MKygOViIWBxkjsRkaysClg7duyo4TKIqKo0hcVwc1ZCqRDM9qmUXKaBiEhOkia5E5H8crUl8LDQewWwB4uISG7VelTOxYsXcf78eWRnZxtXcy9v4MCB1fl4IqpEbmEJ3NWW/worFQKK+agcIiLZSApYFy9exAsvvIDt27cDgMVwJQgCdDpd9aojogrdKiyBh4v5WnRA6RAhe7CIiOQjKWCNGDEC+/fvx7Rp09CtWzd4eXnZui4iuou7DRGW6EWIomh2gwoREdU8SXOw/vjjD0ydOhXvvvsu/vWvf6FXr14WX7Xl5s2bGDNmDHx9fVGvXj1ERkbiyJEjVrc/ffo0Hn/8cbi7u8PHxwfPP/88rl27Vmmbr7/+GoIgwN3dvbrlE0miKSyuNGABYC8WEZFMJPVgNWnSBN7e3rauRRK9Xo+oqCgcP34ckydPRsOGDbF8+XL07t0bhw8fNltK4k6XLl1Cz5494eXlhblz5yI3NxcffPABTp48iaSkJDg7O5u1yc3NxZQpU1CvXr2aOi2iu8rOL0JTHzeL+1TK0oBVohdh4VnQRERUwyT1YE2aNAmffvop8vPzbV1PlSUmJmLfvn1YvXo1Zs+ejVdeeQU7duyAUqnE7Nmz79p+7ty5yMvLw++//45x48ZhxowZWLduHY4fP47Vq1dbbPPOO+/Aw8MDTz/9tG1PhqgKbuQWoYG72uI+paL0r3YJe7CIiGQhqQcrLi4OOp0OrVu3RnR0NJo0aQKl0vSfyYIgYMKECTYpsjKJiYnw9/c3uWPR19cXsbGx+Oqrr6DVaqFWW/4hBAAbNmzAk08+iaZNmxq39e3bFyEhIVi3bh3GjBljcvy5c+ewePFifPfdd1i3bp3tT4jICqIolgaseuY9rADgZBgi5FpYRESykBSw/vzzT8yfPx+ZmZlYtmyZxWNqK2AdPXoUnTt3hkJh2hkXERGBlStX4uzZs+jYsaPFtunp6bh69Sq6du1qti8iIsLi8xRfe+01REZGon///lYHLK1WC61Wa3yv0WisakdUkVvaEhTp9GjgbjlgGRYfLebjcoiIZCEpYI0ZMwY5OTlYsWKF7HcRZmZmomfPnmbbAwICAJQ+H7GigJWZmWly7J3ts7KyTHrAfvzxR2zdurXKz1icN28e4uPjq9SGqDI3cosAAA3qWe6ddVKW/oODk9yJiOQhKWAdO3YM8fHx+Pe//23TYvR6PYqKiqw6Vq1WQxAEFBQUWBwCdHFxAQAUFBRU+BmGfXdrr1arUVRUhAkTJuCll15Cu3btrKrRYPr06Zg4caLxvUajQVBQUJU+g6i867mlPaJ37cHiYqNERLKQFLBatGhh6zoAALt27UJkZKRVx54+fRqhoaFwdXU1GX4zKCwsBAC4urpW+BmGfda0X7x4Ma5fvy6pJ0qtVlc6D4yoqjJulv7joJGXi8X9xrsIOQeLiEgWkgJWfHw8Jk2ahMGDB9u0JyY0NBQJCQlWHWsY1gsICDAO9ZVn2BYYGHjXz6iovY+PD9RqNXJycvDOO+9g7Nix0Gg0xjlUubm5EEURqampcHNzg5+fn1W1E1XXpewCeLk6wbOildzL5iTqLDxlgYiIap6kgLVr1y7Ur18fbdq0Qd++fREUFGTxLsIlS5ZU6XMbNWqEkSNHVqlNWFgYdu/eDb1ebzLR/cCBA3Bzc0NISEiFbRs3bgxfX18cOnTIbF9SUhLCwsIAANnZ2cjNzcX8+fMxf/58s2NbtGiBAQMG4Pvvv69S7URSpd8sQBPvintnlVxolIhIVpIC1n//+1/j7zdv3mzxGCkBS4ro6GgkJiZi48aNiI6OBgBcv34d69evx1NPPWUyNJeSkgIAaNmypXHbs88+i88//xxpaWnG3rht27bh7Nmzxrsg/fz88N1335l999KlS7F//36sXbvW4kR5oppyKbsAjetXHLAMK7lziJCISB6SApbejm79jo6OxgMPPIBRo0bh1KlTxpXcdTqd2XypPn36AABSU1ON22bMmIH169cjMjIS48ePR25uLhYsWICOHTti1KhRAAA3NzeLi4p+//33SEpK4oKjVOvSsvIR2abiIWn2YBERyUtSwLInSqUSW7ZsweTJk7F06VIUFBQgPDwcq1evRps2be7aPigoCDt37sTEiRMxbdo0ODs7IyoqCgsXLuTEdLJLhcU6/HMjD639K34O5u1H5djPP4aIiO4lgihKnwX7xx9/YPv27bh69SrGjh2L1q1bIz8/H2fOnEFISAgfhFwBjUYDLy8v5OTkwNPTU+5yyMH8lZGDqKV7sHHsg+jc1PIzQf++egt9F+1C4kvd0bW5Ty1XSERUN1Xl57ekZxEWFRVh4MCB6NGjB2bOnImlS5ciLS2t9AMVCjz66KO1Mv+K6F509sotAEBrv4r/AcNnERIRyUtSwJo1axY2b96Mjz76CMnJySjfCebi4oKYmBhs2rTJZkUS0W2nMjRo4u0KjwqWaABuT3LnHCwiInlIClhr167Fyy+/jDFjxsDHx3z4oW3btjh//ny1iyMic4f+ya5waNDAMMmdPVhERPKQFLCuXr1a4fP9gNKJ5/n5+ZKLIiLLCot1+DM9B12bVx6wbvdgcZI7EZEcJAWsoKAgnDlzpsL9e/fuRatWrSQXRUSWHb14E8U6EV2aWdmDxXWwiIhkISlgPffcc1ixYgX2799v3CYIpf9BX7VqFdatW4fhw4fbpkIiMtqRfBUN3Z3RtlHld68YH5XDIUIiIllIWgdr5syZ+OOPP9CzZ0+0bdsWgiBgwoQJyMrKwqVLl9C/f3/jKuhEZDu/nr6CPqH+UJT1UFVEqeQcLCIiOUnqwXJ2dsbPP/+MhIQEBAcHIzQ0FFqtFvfddx9Wr16N//u//zN7NiERVc/fV2/h/LU89Gl794eK8y5CIiJ5SV7JXRAEDBs2DMOGDbNlPURUgfWHLqG+mxN6tfG967G8i5CISF6SerCIqHYV6/TYcOQSnunUGGrV3XuHlQLvIiQikpPkHqw9e/bgs88+w/nz55GdnY07n7gjCAKOHz9e7QKJCNh8IgPXc4swOLypVccrFAIUAnuwiIjkIilgLVq0CJMnT4aLiwvatGljcbFRIrINvV7Ef3//G31C/dCmkYfV7VQKBZdpICKSiaSAtWDBAvTo0QP/93//By8vL1vXRETl/N+JDKRcy8OCmPur1E6pENiDRUQkE0lzsPLz8zF06FCGK6IalqctwbwtZ/BoO/+7Ph7nTiqFwDlYREQykRSwIiMjcfLkSVvXQkR3WPb738jOL8KsJ9tVua1SyR4sIiK5SApYy5Ytw7Zt2/DBBx8gKyvL1jUREYCDqVlYuSsFrz7SCkE+blVur1II0HEOFhGRLCQ/izAuLg7Tpk2Dr68v6tWrB09PT5MXhw+JpNMUFuO1b46hc1NvvNSrpaTP4BwsIiL5SJrk/uabb+Ldd99F48aN0bVrV4YpIhsq0enx6pqj0BQW45sxD0CllLZcnUqh4EruREQykRSwPv74Y0RFReH777+HQsG1Sols6Z0fT2PP39exelS4pKFBAxXnYBERyUZSOioqKkJUVBTDFZGNLd/xN1bvS8Wcp9rh4dZ3fyROZZS8i5CISDaSEtKTTz6J3bt327oWonvaql3nMf/nZIzv0xrPd29e7c9TcQ4WEZFsJAWs2bNn49SpUxg7diwOHz6Ma9euISsry+xFRHcniiI+2pGCd7ecxiuRLfFa39Y2+Vwl52AREclG0hysNm3aAACOHTuGFStWVHicTqeTVhXRPUKnF/H25lNYvS8V4/q0xoS+rSGUPai5utiDRUQkH8l3EdrqhwDRvSq/qAQTvz2OracuY+4zHfFcN+se5GwtJdfBIiKSjaSANWfOHBuXQXRvSb2eh5e+OoyLWflY8XxX9Gvnb/PvYA8WEZF8JAUsIpJu2+kreO3bY2jorsb3r/RAiL9HjXwP7yIkIpIPAxZRLSks1mHh1mSs2n0B/dr5Y2Hs/fB0caqx7+M6WERE8mHAIqoFf6bnYOK6Y0i9no8Z/UPx4kPBUChqdh4j7yIkIpIPAxZRDSrR6bFi13l8+NtZtPbzwP+9+hDaNKqZIcE7cQ4WEZF8GLCIasiF63mYuO4YjqfdxMu9W2J8nxA4q2rv6Qelc7AYsIiI5MCARWRjoijiqwMXMffH0/DzVGP9S93RpZlPrdehUgjQlnCSOxGRHBiwiGzoiqYQUxJPYOfZaxjarSlm9G+Lemp5/prxLkIiIvkwYBHZyM9/ZmLaxpNwUiqQMCockW38ZK1HpRBQwoVGiYhkwYBFVE252hLE//AX1h++hMfbN8LcgR3hU89Z7rJ4FyERkYwYsIiqIeVaLsZ8cQiXcwoxP/o+xHRpYjePkeJdhERE8mHAIpLo11NXMOHbY2jk5YIfXn0ILX3d5S7JhFLJuwiJiOTCgEUkwdqki5jx3Uk82s4fC2PD4C7TRPbKsAeLiEg+9vdTgcjOfbwzBe/9dAYjujfD7Kfa1/iK7FLxLkIiIvkwYBFVwZd//IP3fjqD/0S2wuuPhtjNfCtL2INFRCSf2ltWmsjB/fxnJt7c9CdGPtjc7sMVwLsIiYjkxIBFZIW/r97CxHXH0b9DAN58sp3dhyuA62AREcmJAYvoLvKLSvDyV0cQWN8V86Pvs9s5V3fiswiJiORTJwLWzZs3MWbMGPj6+qJevXqIjIzEkSNHrG5/+vRpPP7443B3d4ePjw+ef/55XLt2zeKxKSkpeO655+Dn5wdXV1e0bt0aM2fOtNWpkB364JezSMvOx8fDOsv22BspOAeLiEg+jvPTogJ6vR5RUVE4fvw4Jk+ejIYNG2L58uXo3bs3Dh8+jNatW1fa/tKlS+jZsye8vLwwd+5c5Obm4oMPPsDJkyeRlJQEZ+fbK3IfO3YMvXv3RuPGjfH666+jQYMGuHjxItLS0mr6NEkmRy5mI2HfBcx4oi1a+XnIXU6VlK6DxbsIiYjk4PABKzExEfv27cP69esRHR0NAIiNjUVISAhmz56NNWvWVNp+7ty5yMvLw+HDh9G0aVMAQEREBPr164fVq1djzJgxAEqD3PPPP4/Q0FBs374drq6uNXtiJDudXsSMjSdxX2MvjOrRXO5yqow9WERE8nH4IcLExET4+/tj4MCBxm2+vr6IjY3Fpk2boNVqK22/YcMGPPnkk8ZwBQB9+/ZFSEgI1q1bZ9y2detW/Pnnn5g9ezZcXV2Rn58PnU5n+xMiu7Hh8CWcuXwLbw3oAJXS8f6q8C5CIiL5ON5PjTscPXoUnTt3hkJheioRERHIz8/H2bNnK2ybnp6Oq1evomvXrmb7IiIicPToUeP73377DQCgVqvRtWtX1KtXD25ubhg8eDCysrIqrVGr1UKj0Zi8yL4VFOmw6NezePK+ANwfVF/uciRhDxYRkXwcPmBlZmYiICDAbLthW0ZGRqVtyx97Z/usrCxjD9i5c+cAlA4/hoaGIjExEVOnTsWGDRvw1FNPQRQr/kE2b948eHl5GV9BQUHWnyDJ4qs//sH1XC0mP9ZG7lIkUyoElOg4B4uISA52NQdLr9ejqKjIqmPVajUEQUBBQQHUarXZfhcXFwBAQUFBhZ9h2He39mq1Grm5uQCA8PBwfPXVVwCAZ599Fm5ubpg+fTq2bduGvn37Wvye6dOnY+LEicb3Go2GIcuOFZXo8cme83imU2M0a1BP7nIkUykE6EVArxcdZmkJIqK6wq56sHbt2gVXV1erXsnJyQAAV1dXi/OsCgsLjfsrYthnTXvDr0OGDDE57rnnngMA7Nu3r8LvUavV8PT0NHmR/dp0LB1XNFqM6RksdynVoiwLVbpKeleJiKhm2FUPVmhoKBISEqw61jCsFxAQYBzqK8+wLTAw8K6fUVF7Hx8fY++W4XP8/f1NjvPz8wMAZGdnW1U32TdRFLFy13n0beuH1v6OtSzDnVTKsoClF+GklLkYIqJ7jF0FrEaNGmHkyJFVahMWFobdu3dDr9ebTHQ/cOAA3NzcEBISUmHbxo0bw9fXF4cOHTLbl5SUhLCwMOP7Ll26YNWqVUhPTzc5zjDHy9fXt0p1k33af/4Gzl3NxVsDOshdSrUpy/4+cKI7EVHts6shQimio6Nx5coVbNy40bjt+vXrWL9+PZ566imT+VUpKSlISUkxaf/ss89i8+bNJouFbtu2DWfPnkVMTIxx24ABA6BWq5GQkAB9ucUbP/nkEwBAv379bH5uVPu+PZiGYN96eCDYR+5Sqk1lGCLk8wiJiGqdXfVgSREdHY0HHngAo0aNwqlTp4wruet0OsTHx5sc26dPHwBAamqqcduMGTOwfv16REZGYvz48cjNzcWCBQvQsWNHjBo1ynhco0aNMHPmTLz55pt4/PHH8fTTT+P48eNYtWoVhgwZgvDw8Fo5X6o5N/OL8NOflzHp0RCHeJjz3RjmYJVwNXciolrn8AFLqVRiy5YtmDx5MpYuXYqCggKEh4dj9erVaNPm7rfYBwUFYefOnZg4cSKmTZsGZ2dnREVFYeHChWZ3F77xxhvw9vbGsmXL8Nprr5mELnJ8G4+kQxRFPNu5idyl2ISxB4tDhEREtU4QK1vAiWqERqOBl5cXcnJyeEehHYlauhtNfdzw0bAucpdiEzvPXsOIz5Kwb9ojCKzPRzsREVVXVX5+O/wcLCJbOH8tF39laDAgrOK7Th0Ne7CIiOTDgEUEYPOJTNRzVqJ3Gz+5S7GZ23OwGLCIiGobAxYRgM0nMtCvnT9c6tCCUbd7sDjJnYiotjFg0T0v+fItnL2SiyfvqzvDgwB7sIiI5MSARfe8LScz4eGiwsMhDeUuxaZUhoVGuQ4WEVGtY8Cie962M1cQ2cYPalXdGR4Eyj2LkD1YRES1jgGL7mmXcwrxZ7oGfdrWncntBoZnEXKIkIio9jFg0T3t9zNXoRCAXiF171mS7MEiIpIPAxbd034/cwVdm/mgvpuz3KXYnIqPyiEikg0DVh0iiiLWJl3E5/tS8ffVW+Ai/ZUrLNZhz9/X6+TwIMAeLCIiOTn8swjptvPX8zB940njez8PNR5s2QAPtmyIsKb1EdywHlRKZmqD/Sk3UFisr7MBy3gXIQMWEVGtY8CqQ1r6umP/9Efg5qzCsbSb2Pf3dexNuY5NxzMgioCLkwJtAzzRPtATLRq6o0VDNzRvUA9BPm5wugeD156/ryPAywUtfd3lLqVGGHuwuEwDEVGtY8CqYwK8Sh/q2yvE1zhxW1NYjFMZGvyZnoO/MjQ4eCEb6w9dgrakdG6OUiHA30MNP08X+Huq4e/pAn9PF/h6qOHt5gwvVyfUd3OCl2vpq66sdn7kYjYiWvhAEAS5S6kRKi40SkQkGwase4CnixMeCG6AB4IbGLfp9SIuawqRej0PF27kIfNmIa5oCnHllhZJF7JwRVOI7Pxii5+nVing6eoEN2cl3JxVZb8qje9dnZWo56yEq7MKLk4KqFVKOKsUUCsVpb+qSn91VingrFRA7aSEc7l9TkoFlAoBTkqh7NfS9yqFYNMwlJVXhIgWPjb7PHujVHIOFhGRXBiw7lEKhYDA+q4IrO+KB1tZXsG8qEQPTWExbuYXI6egGDkFRcgpKH2vKShBfnEJCop0yNPqUFBcgjytDtl5BcgvLkG+Vof8Ih0KinUoKtGjSKe3yQ96Q9C6M4SpFAqolKX7TH5vcpwCTgoBqrI2mTmF8K6Ddw8a8C5CIiL5MGBRhZxVCjR0V6Ohu9omn6fTi6Vhq0QPbYkO2rLgZdhWpNNDW6xHiV6PEp2IEr1o+nud3vRXvQidXkRxWXgr1onQ6fVlv5a2Nfy+/DHaktLfd2vhg4cqCJd1Ae8irJxeL+JWYQmy84uQnV+Em/nFuKUtQWGRDoUlOhSU/QOhoFiHwiIddKIInb60nV4UoRNFiGLp9S39vQgBAgQBUAgCFIZfFbd/L5TfLqDsvQClwvRYZdmxSkNbhQBl2bHGY8p6dJXC7WNMPqvcZxuPK9unVAjljin3WYry9Zl+v6LsM4Sy40vbwGJdlj6b6F7DgEW1RqkQ4OqshKuzEoCT3OXUeff6XYR6vYhL2QU4e+UW/snKR3p2AdJv5iPjZiEycwqQnV9cYfh0Virg4qQo/fPqpIRapYRKKZiFoDtDBQDoRRF6femvolj2XhShF0uXUtEbt5XWaAhnhu06vXlw0+lvH28Id+XfO8L/xZWFt9uBslw4VJiHt8qCX/nwWBooYRb8ygdSQ+gTjP8DCGW/EYzvYXxvts+YGQWLxxs+z3zf7bApVPK9t79HMGkPS7VY8b0o9zlV+d47a3UksV2DbNZBIAUDFlEdVdaBdU/0YOn1IlKu5eLIxWwc+ecm/srMwd9Xc1FYXDo86uKkQOOyIfH2gZ7o184fPvWc4e3mDG83J3iX/d7DRQUXJ6Wx989RWAxohmBXFs5Kt5uGM50xoN0+pnxAvB3wYPysO8OdMfyJollAvL2tXNDUi9CVhU2Ttnd8tjX1Gz7bsN3yd4soKn+e+tJrU3rhABFi2TU0bjJeU8P7O/fB4r47Pkc0/6zyzSv73tvfU/G+yr63/J8L0/aVfe/td5ZqcsReyH5t/RmwiMj2BKF0Hlpd7cFKy8rHzrPXsCP5GpIu3ICmsASCALTx90DHxl4YcH9jtPZ3R4i/BwK8XBzyB4S1DD02SgioIzf5Ejk8BiyiOkypEKDT1Z1J7mcua/DDsQz88tdlpFzLg1IhoEszb7z4cDA6N/XG/UFe8HDh8DMRyY8Bi6gOqws9WFc0hUg8fAk/HMtA8pVb8HJ1wmPt/THp0Tbo0bohPBmoiMgOMWAR1WFKheCQc7BEUcS+lBv46o9/sPXUFTgrFXi0vT+mPN4GD7f2hbPq3nvyABE5FgYsojpMpVQ4VA9WsU6P74+m4+OdKUi5lofWfu6Y/VQ7PNOpMYf+iMihMGAR1WGO0oNVrNNj45FL+N/2FFzMysej7fwx95mOdfpRRkRUtzFgEdVh9j4Hq6hEjw1HLuF/2//GpewCPNGhET4e1gXtAj3lLo2IqFoYsIjqMKVCQIkd3kVYVKLH+sNpWL49BRk5BejfIQCfjOiK0EYMVkRUNzBgEdVh9ZxVyC/SVeszsvOK8MqaI+jfMQDDHmhWrc/Sluiw7tAlfLT9b2RqChHVMQAJfcIR4u9Rrc8lIrI3DFhEdZiHiwqawmLJ7dNvFmBUQhLOXslFIy8XyQGrsFiHbw+m4aMdKbh6qxBP3R+I/0S2QmsGKyKqoxiwiOowDxcVbhWWSGp7MDULL315GC5OSrQP9ERWXlGVPyO/qARrDlzEyl3ncT1XiwFhjfGfR1qhpa+7pJqIiBwFAxZRHebh4oSrtwqr1KZEp8dHO1KwZNs5dGnmjY+GdcFney7gi/2pyNWWwF199/9s5BQU48v9qfh0zwXcKizBM50a4+XeLRHMYEVE9wgGLKI6zMNFhZRr1vdgHf4nG/H/9xf+TM/By71b4rW+IXBSKjCkW1N8suc8PvglGXP+1b7C9n9l5OCrP/7B90czoBNFDOoahLhewWji7WaL0yEichgMWER1mJerE27m330O1p/pOfjf9r/x05+X0TbAExtefhCdmnob9zeu74opj4Xirc2nIAjACz1aoHF9V9wqLMGpTA32p1zHz39dLp2r5emCl3u3xOCIIPh5uNTk6RER2S0GLKI6LMjHDZk5BSgq0Zs9XianoBi/nbqCbw5exMHUbDSu74qFMffj6U6NoVSYL+45qkdz6EURC35JRsLeVJN9Hi4q9Gvrj8mPhSKyjS9USj7KhojubQxYRHVY8wb1oBeBlGu5CPH3wOlMDQ5cyMLuc9ew9+/rKNaJeCDYBx8P64y+bf0rDUaCIODFh4MRGx6EP1Ju4EZeEdzVKrRp5IGWvu4WQxkR0b1KEEXRfpd5rqM0Gg28vLyQk5MDT08urEg1p7BYh25zt8FZpUBhkQ63tCVwVinQpak3Hm3vjyc6BKCRF4fxiIisUZWf3+zBIqrDXJyU+HREV3x/LB0BXq7o2swb9wfVh4uTUu7SiIjqNAYsojqua3MfdG3uI3cZRET3FM5EJSIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG6sTAevmzZsYM2YMfH19Ua9ePURGRuLIkSNWtz99+jQef/xxuLu7w8fHB88//zyuXbtmdlxmZibGjBmDFi1awNXVFS1btsTEiRNx48YNW54OEREROTiHXwdLr9fj4YcfxvHjxzF58mQ0bNgQy5cvR1paGg4fPozWrVtX2v7SpUvo1KkTvLy8MG7cOOTm5uKDDz5A06ZNkZSUBGdnZwBAbm4uOnTogLy8PIwdOxZBQUE4fvw4VqxYgfbt2+Pw4cNQKKzLq1wHi4iIyPHcU+tgJSYmYt++fVi/fj2io6MBALGxsQgJCcHs2bOxZs2aStvPnTsXeXl5OHz4MJo2bQoAiIiIQL9+/bB69WqMGTMGAPDDDz/gn3/+webNmxEVFWVs7+Pjg7feegvHjx9Hp06daugsiYiIyJE4/BBhYmIi/P39MXDgQOM2X19fxMbGYtOmTdBqtZW237BhA5588kljuAKAvn37IiQkBOvWrTNu02g0AAB/f3+T9gEBAQAAV1fXap8LERER1Q0OH7COHj2Kzp07mw3PRUREID8/H2fPnq2wbXp6Oq5evYquXbua7YuIiMDRo0eN73v27AmFQoHx48fjjz/+wKVLl7Blyxa8++67ePrppxEaGmq7kyIiIiKH5vABKzMz09iLVJ5hW0ZGRqVtyx97Z/usrCxjD1i7du2wcuVKnDp1Ct27d0dQUBCioqLQp08frF+/vtIatVotNBqNyYuIiIjqLruag6XX61FUVGTVsWq1GoIgoKCgAGq12my/i0vpA2wLCgoq/AzDvru1N+xv3LgxIiIi0L9/fzRr1gy7d+/G0qVL0bBhQ3zwwQcVfs+8efMQHx9v1XkRERGR47OrgLVr1y5ERkZadezp06cRGhoKV1dXi/OsCgsLAVQ+N8qwz5r2e/fuxZNPPok//vjDOKT49NNPw9PTE/Hx8XjhhRfQrl07i98zffp0TJw40fheo9EgKCjImtMkIiIiB2RXASs0NBQJCQlWHWsY1gsICDAO9ZVn2BYYGHjXz6iovY+Pj7H3asWKFfD39zebr/Wvf/0Lc+bMwb59+yoMWGq12mIvGREREdVNdhWwGjVqhJEjR1apTVhYGHbv3g29Xm8y0f3AgQNwc3NDSEhIhW0bN24MX19fHDp0yGxfUlISwsLCjO+vXLkCnU5ndlxxcTEAoKSkpEp1ExERUd1lVwFLiujoaCQmJmLjxo3GdbCuX7+O9evX46mnnjLpOUpJSQEAtGzZ0rjt2Wefxeeff460tDTjsN22bdtw9uxZTJgwwXhcSEgItm7dih07dqB3797G7WvXrgWAKq2BZVjblZPdiYiIHIfh57Y1a7Q7/EruOp0ODz30EP7880+TldwvXryIgwcPok2bNsZjmzdvDgBITU01bktLS0OnTp1Qv359jB8/Hrm5uViwYAGaNGmCgwcPGgNacnIyunTpAkEQ8Oqrr6JZs2bYuXMn1q5di379+mHr1q1W13zp0iXOwSIiInJQaWlpaNKkSaXHOHzAAoDs7GxMnjwZ33//PQoKChAeHo4PPvjAbL6UpYAFAH/99RcmTpyIPXv2wNnZGVFRUVi4cKHZoqLJycl44403cODAAVy+fBmBgYGIiYlBfHw83NzcrK5Xr9cjIyMDHh4eEARB0jlXxDCBPi0tjY/huQteK+vxWlmP18p6vFbW47WyXk1eK1EUcevWLQQGBt718Xh1ImDRbXzOofV4razHa2U9Xivr8VpZj9fKevZyrRx+oVEiIiIie8OARURERGRjDFh1jFqtxuzZs7nulhV4razHa2U9Xivr8VpZj9fKevZyrTgHi4iIiMjG2INFREREZGMMWEREREQ2xoBFREREZGMMWEREREQ2xoDlILRaLaZOnYrAwEC4urqiW7du+PXXX61qm56ejtjYWNSvXx+enp4YMGAAzp8/X8MVy0fqtUpOTsaECRPw4IMPwsXFBYIgmK36X9dIvVYbN27EoEGDEBwcDDc3N7Rp0wavv/46bt68WfNFy0Tqtfruu+/w2GOPITAwEGq1Gk2aNEF0dDT+/PPPWqhaHtX571V5/fr1gyAI+M9//lMDVdoHqddqzpw5EATB7OXi4lILVcujun+uvv32W3Tv3h316tVD/fr18eCDD+L333+vuYJFcgiDBw8WVSqVOGnSJHHFihVi9+7dRZVKJe7evbvSdrdu3RJbt24t+vn5ie+//764aNEiMSgoSGzSpIl4/fr1Wqq+dkm9VgkJCaJCoRA7dOgghoWFiQDECxcu1E7RMpF6rRo0aCB27NhRnDVrlrhq1Spx3LhxorOzsxgaGirm5+fXUvW1S+q1io+PFwcNGiS+99574ieffCK+8847YnBwsOjq6ioeO3aslqqvXVKvVXkbNmwQ69WrJwIQX3nllRqsVl5Sr9Xs2bNFAOJHH30kfvnll8bXmjVraqny2ledP1ezZ88WBUEQY2JixI8//lhctmyZGBcXJ37xxRc1Vi8DlgM4cOCACEBcsGCBcVtBQYHYsmVLsXv37pW2ff/990UAYlJSknHb6dOnRaVSKU6fPr3GapZLda7VjRs3RI1GI4qiKC5YsKDOB6zqXKvt27ebbfv8889FAOKqVatsXarsqnOtLLl8+bKoUqnEuLg4W5ZpF2xxrQoKCsTmzZuLb731Vp0OWNW5VoaAde3atZou0y5U51rt379fFARBXLRoUU2XaYJDhA4gMTERSqUSY8aMMW5zcXHB6NGjsX//fqSlpVXaNjw8HOHh4cZtoaGh6NOnD9atW1ejdcuhOtfKx8cHHh4etVGmXajOterdu7fZtmeeeQYAcPr0aZvXKrfqXCtL/Pz84ObmVieHVG1xrebPnw+9Xo9JkybVZKmys8W1EkURGo0GYh1f0rI61+rDDz9Eo0aNMH78eIiiiNzc3NoomXOwHMHRo0cREhJi9tDKiIgIAMCxY8csttPr9Thx4gS6du1qti8iIgIpKSm4deuWzeuVk9RrdS+y9bW6fPkyAKBhw4Y2qc+e2OJa3bx5E9euXcPJkyfx4osvQqPRoE+fPjVRrqyqe60uXryI9957D++//z5cXV1rqky7YIs/V8HBwfDy8oKHhweGDRuGK1eu1ESpsqvOtdq2bRvCw8OxdOlS+Pr6wsPDAwEBAfjvf/9bkyVDVaOfTjaRmZmJgIAAs+2GbRkZGRbbZWVlQavV3rVtmzZtbFitvKReq3uRra/V+++/D6VSiejoaJvUZ09sca0eeOABJCcnAwDc3d3xxhtvYPTo0bYt1A5U91q9/vrr6NSpEwYPHlwj9dmT6lwrb29v/Oc//0H37t2hVquxe/du/O9//0NSUhIOHTpkFkQcndRrlZ2djevXr2Pv3r34/fffMXv2bDRt2hQJCQl49dVX4eTkhLi4uBqpmQHLARQUFFh8ppLhbpGCgoIK2wGQ1NZRSb1W9yJbXqs1a9bg008/xZQpU9C6dWub1WgvbHGtEhISoNFocP78eSQkJKCgoAA6nQ4KRd0aSKjOtdq+fTs2bNiAAwcO1Fh99qQ612r8+PEm75999llERERg6NChWL58OaZNm2bbYmUm9VoZhgNv3LiBb775BoMGDQIAREdHo2PHjnjnnXdqLGDVrb/ZdZSrqyu0Wq3Z9sLCQuP+itoBkNTWUUm9VvciW12r3bt3Y/To0Xjsscfw7rvv2rRGe2GLa9W9e3c89thjePnll/HLL7/gq6++wvTp021eq9ykXquSkhKMGzcOzz//vMmc0brM1v+9eu6559CoUSP89ttvNqnPnlT356CTk5NJ77pCocCgQYNw6dIlXLx4sQYqZsByCAEBAcjMzDTbbtgWGBhosZ2Pjw/UarWkto5K6rW6F9niWh0/fhz/+te/0KFDByQmJkKlqpud4rb+c+Xt7Y1HHnkEX3/9tU3qsydSr9UXX3yB5ORkxMXFITU11fgCgFu3biE1NRX5+fk1VrccauK/V0FBQcjKyqp2bfamOj8HXVxc0KBBAyiVSpN9fn5+AEqHEWsCA5YDCAsLw9mzZ6HRaEy2G7rRw8LCLLZTKBTo2LEjDh06ZLbvwIEDCA4OrnN3zUm9Vvei6l6rlJQUPP744/Dz88OWLVvg7u5eU6XKrib+XBUUFCAnJ8cW5dkVqdfq4sWLKC4uRo8ePdCiRQvjCygNXy1atMDWrVtrtPbaZus/V6IoIjU1Fb6+vrYq0W5U5+dgWFgYrl27hqKiIpN9hnlbNXa9anVRCJLkjz/+MFv/o7CwUGzVqpXYrVs347Z//vlHPH36tEnb9957TwQgHjx40LjtzJkzolKpFKdOnVrzxdey6lyr8u6FdbCqc60yMzPF4OBgMTAwsE5fI4PqXKsrV66Yfd6FCxdEDw8P8eGHH665omUi9VqdPn1a/O6778xeAMT+/fuL3333nZiRkVGr51LTqvPn6urVq2af97///U8EUOvrPdWG6lyrxYsXiwDElStXGrcVFBSIwcHBYrt27WqsZgYsBxETEyOqVCpx8uTJ4ooVK8QHH3xQVKlU4s6dO43H9OrVS7wzM2s0GrFly5ain5+fOH/+fHHx4sViUFCQGBgYaPEvaF0g9VrdvHlTfPvtt8W3335bfPzxx0UA4uuvvy6+/fbb4rJly2r7NGqF1Gt1//33iwDEKVOmmKwi/eWXX4pbt26t7dOoFVKvlZ+fnzhkyBDx/fffF1euXClOnjxZ9PHxEV1cXMS9e/fW9mnUCqnXyhLU4YVGRVH6tXJ1dRVHjhwpLly4UPzf//4nDhkyRBQEQQwLCxPz8vJq+zRqhdRrlZ+fL7Zv3150cnISJ02aJC5dulQMDw8XlUqluGXLlhqrlwHLQRQUFIiTJk0SGzVqJKrVajE8PFz8+eefTY6p6D9YaWlpYnR0tOjp6Sm6u7uLTz75pHju3LnaKr3WSb1WFy5cEAFYfDVr1qwWz6D2SL1WFV0nAGKvXr1q8Qxqj9RrNXv2bLFr166it7e3qFKpxMDAQHHw4MHiiRMnarP8WlWd/17dqa4HLKnX6sUXXxTbtWsnenh4iE5OTmKrVq3EqVOnGp9GURdV58/VlStXxBEjRog+Pj6iWq0Wu3XrZtbW1gRRrOPLvxIRERHVMk5yJyIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiuuc0b94cI0eOlLsMM2PHjkW/fv2q1Objjz9G06ZNodVqa6gqIpKCAYuI6qR9+/Zhzpw5uHnzptylWOXChQv45JNPMGPGjCq1GzlyJIqKirBixYoaqoyIpGDAIqI6ad++fYiPj7cYsJKTk7Fq1araL6oSS5YsQYsWLRAZGVmldi4uLhgxYgQWLVoEPlqWyH4wYBHRPUetVsPJyUnuMoyKi4vx9ddfIzY2VlL72NhY/PPPP9i+fbuNKyMiqRiwiKjOmTNnDiZPngwAaNGiBQRBgCAISE1NBWA+B2v16tUQBAF79uzBuHHj4Ovri/r16yMuLg5FRUW4efMmhg8fDm9vb3h7e2PKlClmvUV6vR4ffvgh2rdvDxcXF/j7+yMuLg7Z2dl3rXfPnj24fv06+vbta7Zv2bJlaN++Pdzc3ODt7Y2uXbtizZo1Jsd06dIFPj4+2LRpUxWvFBHVFJXcBRAR2drAgQNx9uxZrF27FosXL0bDhg0BAL6+vpW2e/XVV9GoUSPEx8fjjz/+wMqVK1G/fn3s27cPTZs2xdy5c7FlyxYsWLAAHTp0wPDhw41t4+LisHr1aowaNQrjxo3DhQsX8N///hdHjx7F3r17K+0x27dvHwRBQKdOnUy2r1q1CuPGjUN0dDTGjx+PwsJCnDhxAgcOHMBzzz1ncmznzp2xd+/eql4qIqopIhFRHbRgwQIRgHjhwgWzfc2aNRNHjBhhfJ+QkCACEB977DFRr9cbt3fv3l0UBEF86aWXjNtKSkrEJk2aiL169TJu2717twhA/Prrr02+5+eff7a4/U7Dhg0TGzRoYLZ9wIABYvv27e9ypqXGjBkjurq6WnUsEdU8DhESEZUZPXo0BEEwvu/WrRtEUcTo0aON25RKJbp27Yrz588bt61fvx5eXl7o168frl+/bnx16dIF7u7ud50bdePGDXh7e5ttr1+/Pi5duoSDBw/etXZvb28UFBQgPz/fmlMlohrGgEVEVKZp06Ym7728vAAAQUFBZtvLz606d+4ccnJy4OfnB19fX5NXbm4url69etfvFi3cATh16lS4u7sjIiICrVu3xiuvvFLhMKChffmASETy4RwsIqIySqXS6u3lA5Fer4efnx++/vpri+3vNverQYMGFifDt23bFsnJydi8eTN+/vlnbNiwAcuXL8ebb76J+Ph4k2Ozs7Ph5uYGV1fXSr+LiGoHAxYR1Um12ZPTsmVL/Pbbb+jRo4ekgBMaGoqvv/4aOTk5xl4zg3r16mHQoEEYNGgQioqKMHDgQLz77ruYPn06XFxcjMdduHABbdu2rfa5EJFtcIiQiOqkevXqAUCtrOQeGxsLnU6Ht99+22xfSUnJXWvo3r07RFHE4cOHTbbfuHHD5L2zszPatWsHURRRXFxssu/IkSN48MEHpZ0AEdkce7CIqE7q0qULAGDmzJkYPHgwnJyc8NRTTxmDly316tULcXFxmDdvHo4dO4ZHH30UTk5OOHfuHNavX48lS5YgOjq6wvYPPfQQGjRogN9++w2PPPKIcfujjz6KRo0aoUePHvD398fp06fx3//+F1FRUfDw8DAed/jwYWRlZWHAgAE2PzcikoYBi4jqpPDwcLz99tv4+OOP8fPPP0Ov1+PChQs1ErCA0ocud+nSBStWrMCMGTOgUqnQvHlzDBs2DD169Ki0rbOzM4YOHYr169dj7ty5xu1xcXH4+uuvsWjRIuTm5qJJkyYYN24c3njjDZP269evR9OmTU3CGRHJSxAt3bpCRES16vz58wgNDcVPP/2EPn36WN1Oq9WiefPmmDZtGsaPH1+DFRJRVXAOFhGRHQgODsbo0aPx3nvvValdQkICnJyc8NJLL9VQZUQkBXuwiIiIiGyMPVhERERENsaARURERGRjDFhERERENsaARURERGRjDFhERERENsaARURERGRjDFhERERENsaARURERGRjDFhERERENsaARURERGRj/w+rFP6G77z2ygAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAG4CAYAAACZypnDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAABf2klEQVR4nO3deVxU5f4H8M+ZGRhAFkEBQXFBRdwKFzCzVFJbpK5lgJrmkl0pu2mau5nSoqWpqfdaaoVtWoqW/czKMndN3LVUNJREwBVkZBtg5vz+gBkZZ8DhMHBm8PN+vebqnHOeme85V+Pj8zznOYIoiiKIiIiIyGYUchdAREREVNcwYBERERHZGAMWERERkY0xYBERERHZGAMWERERkY0xYBERERHZGAMWERERkY2p5C7gXqTX65GRkQEPDw8IgiB3OURERGQFURRx69YtBAYGQqGovI+KAUsGGRkZCAoKkrsMIiIikiAtLQ1NmjSp9BgGLBl4eHgAKP0/yNPTU+ZqiIiIyBoajQZBQUHGn+OVYcCSgWFY0NPTkwGLiIjIwVgzvYeT3ImIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLiIiIyMYYsIiIiIhsjAGLyMHp9CImrjuGv6/myl0KERGVYcAicnBZeUXYeCQdc7eclrsUIiIqw4BF5OAKinQASnuyiIjIPjBgETm4vKISAICTUpC5EiIiMmDAInJwRSV6uUsgIqI7MGAROTi9WDo0WKTjECERkb1gwCJycIapV8XsySIishsMWEQOrzRhlegZsIiI7AUDFpGDM/RgcYiQiMh+MGAROTiRQ4RERHanzgQsrVaLqVOnIjAwEK6urujWrRt+/fVXq9qmp6cjNjYW9evXh6enJwYMGIDz589X2mbPnj0QBAGCIOD69eu2OAUiSQyT3A2/EhGR/OpMwBo5ciQWLVqEoUOHYsmSJVAqlejfvz/27NlTabvc3FxERkZi586dmDFjBuLj43H06FH06tULN27csNhGr9fj1VdfRb169WriVIiqxJCrGLCIiOxHnQhYSUlJ+OabbzBv3jwsWLAAY8aMwe+//45mzZphypQplbZdvnw5zp07h82bN2PKlCmYMGECtm7diszMTCxcuNBim5UrVyItLQ0vvvhiTZwOUZWIZcGKK7kTEdmPOhGwEhMToVQqMWbMGOM2FxcXjB49Gvv370daWlqlbcPDwxEeHm7cFhoaij59+mDdunVmx2dlZeGNN97AW2+9hfr169v0PIikMMQqdmAREdmPOhGwjh49ipCQEHh6eppsj4iIAAAcO3bMYju9Xo8TJ06ga9euZvsiIiKQkpKCW7dumWyfNWsWGjVqhLi4OKvr02q10Gg0Ji8iWzEMDeqYsIiI7EadCFiZmZkICAgw227YlpGRYbFdVlYWtFqt1W1PnDiBFStWYNGiRVAqlVbXN2/ePHh5eRlfQUFBVrcluhtDruIQIRGR/agTAaugoABqtdpsu4uLi3F/Re0AWN123LhxeOKJJ/Doo49Wqb7p06cjJyfH+KpsyJKoqox3ETJgERHZDZXcBdiCq6srtFqt2fbCwkLj/oraAbCq7bfffot9+/bhzz//rHJ9arXaYogjsgVDrOIQIRGR/agTASsgIADp6elm2zMzMwEAgYGBFtv5+PhArVYbj6us7eTJkxETEwNnZ2ekpqYCAG7evAkASEtLQ1FRUYXfQ1STbt9FKHMhRERkVCcCVlhYGLZv3w6NRmMy0f3AgQPG/ZYoFAp07NgRhw4dMtt34MABBAcHw8PDA0BpiFqzZg3WrFljdmznzp1x//33VziZnqgmGTquRPZgERHZjToxBys6Oho6nQ4rV640btNqtUhISEC3bt2Mk8ovXryIM2fOmLU9ePCgSchKTk7G77//jpiYGOO27777zuw1aNAgAMAXX3yBxYsX1+QpElXIMPWKQ4RERPajTvRgdevWDTExMZg+fTquXr2KVq1a4fPPP0dqaio+/fRT43HDhw/Hzp07Tf6lP3bsWKxatQpRUVGYNGkSnJycsGjRIvj7++P11183Hvf000+bfa+hx+qJJ55Aw4YNa+z8iCqj50KjRER2p04ELKC0F2nWrFn48ssvkZ2djfvuuw+bN29Gz549K23n4eGBHTt2YMKECXjnnXeg1+vRu3dvLF68GL6+vrVUPZF0t4cI5a2DiIhuE0RO3Kh1Go0GXl5eyMnJMVsclaiqfjqZiZe/PgJXJyVOv/243OUQEdVZVfn5XSfmYBHdy7hMAxGR/WHAInJwXGiUiMj+MGAROThDx5WePVhERHaDAYvIwRl7sJiviIjsBgMWERERkY0xYBE5OA4NEhHZHwYsIgdXPl9xojsRkX1gwCJycOUzVbGeT3wmIrIHDFhEDq78WsHMV0RE9oEBi8jBlR8iLGHCIiKyCwxYRA5OxO2ExQc+ExHZBwYsIgenN+nBYsAiIrIHDFhEDq78ECF7sIiI7AMDFpGDK78OFnuwiIjsAwMWkYMrfxehTseARURkDxiwiBxc+UjFuwiJiOwDAxaRgyu/ejvnYBER2QcGLCIHZ9qDxYBFRGQPGLCIHJyedxESEdkdBiwiByfyLkIiIrvDgEXk4EzXweIkdyIie8CAReTgTB+VI2MhRERkxIBF5OD0fNgzEZHdYcAicnB8VA4Rkf1hwCJycHxUDhGR/WHAIqpD+KgcIiL7wIBF5OD0ehFOSgEAe7CIiOwFAxaRgxMBOClL/ypzDhYRkX1gwCJycHpRhEph6MHiXYRERPaAAYvIwelF9mAREdkbBiwiRyeKxoDFOVhERPaBAYvIwelFQFk2RMgeLCIi+8CAReTgRIhQKACVQmAPFhGRnWDAInJwehEQIECpEKDjwwiJiOwCAxaRgxNFQCGwB4uIyJ4wYBE5OFEUIQilPVjlH5tDRETyYcAicnAiAEEAVEoFe7CIiOwEAxaRg9PrRQhA2RwsBiwiInvAgEXk4EQACkHgHCwiIjvCgEXk4PSiCEEo68FiwCIisgsMWEQOrvQuQvZgERHZEwYsIgcnlt05qFAI0PFhz0REdqHOBCytVoupU6ciMDAQrq6u6NatG3799Ver2qanpyM2Nhb169eHp6cnBgwYgPPnz5sck5aWhvj4eERERMDb2xsNGzZE79698dtvv9XE6RBZjXOwiIjsT50JWCNHjsSiRYswdOhQLFmyBEqlEv3798eePXsqbZebm4vIyEjs3LkTM2bMQHx8PI4ePYpevXrhxo0bxuM2bdqE999/H61atcI777yDWbNm4datW+jXrx8SEhJq+vSIKnR7DpaCc7CIiOyEIIqOvzJhUlISunXrhgULFmDSpEkAgMLCQnTo0AF+fn7Yt29fhW3nz5+PqVOnIikpCeHh4QCAM2fOoEOHDpgyZQrmzp0LAPjrr7/g7++Phg0bGttqtVqEhYUhNzcXaWlpVter0Wjg5eWFnJwceHp6SjllIqMZ353EyUs5AICOTbww95mOMldERFQ3VeXnd53owUpMTIRSqcSYMWOM21xcXDB69Gjs37+/0vCTmJiI8PBwY7gCgNDQUPTp0wfr1q0zbmvfvr1JuAIAtVqN/v3749KlS7h165YNz4jIeoZH5XAdLCIi+1EnAtbRo0cREhJiliYjIiIAAMeOHbPYTq/X48SJE+jatavZvoiICKSkpNw1OF2+fBlubm5wc3Or8BitVguNRmPyIrIVURQBzsEiIrIrdSJgZWZmIiAgwGy7YVtGRobFdllZWdBqtZLaAsDff/+NjRs34tlnn4VSqazwuHnz5sHLy8v4CgoKqvR8iKrCpAeLdxESEdmFageswsJCaLVaW9QiWUFBAdRqtdl2FxcX4/6K2gGQ1DY/Px8xMTFwdXXFe++9V2l906dPR05OjvFVlflaRHejF0sflaNSCuAIIRGRfVBVtcGOHTuwadMm7N27F6dOnTIGEDc3N7Rt2xYPPvggnn76afTu3dvWtVbI1dXVYsgrLCw07q+oHYAqt9XpdBg8eDBOnTqFn376CYGBgZXWp1arLYY4IlswLNNQehche7CIiOyBVQGruLgYK1aswKJFi5CamgofHx907twZw4YNg7e3N0RRRHZ2Ni5cuICvvvoKS5cuRbNmzfD6668jLi4OTk5ONXoSAQEBSE9PN9uemZkJABUGIB8fH6jVauNx1rb997//jc2bN+Prr7/GI488Up3SiarNsEyDSiGghF1YRER2waqA1apVKxQVFWHEiBGIjY1F586dKz3+8OHDWL9+PebOnYsPPvgAqamptqi1QmFhYdi+fTs0Go3JRPcDBw4Y91uiUCjQsWNHHDp0yGzfgQMHEBwcDA8PD5PtkydPRkJCAj788EMMGTLEdidBJJUICILAZxESEdkRq+ZgzZgxA6mpqXjvvffuGq4AoEuXLnjvvfeQmpqK6dOnV7vIu4mOjoZOp8PKlSuN27RaLRISEtCtWzfjpPKLFy/izJkzZm0PHjxoErKSk5Px+++/IyYmxuTYBQsW4IMPPsCMGTMwfvz4GjwjIusZ52DxLkIiIrtRJxYaBYDY2Fh89913mDBhAlq1aoXPP/8cSUlJ2LZtG3r27AkA6N27N3bu3Inyp3zr1i106tQJt27dwqRJk+Dk5IRFixZBp9Ph2LFj8PX1BQB89913GDhwIFq3bo0333zT7Pv79esHf39/q2rlQqNkS+O/OYqrGi183J2Rk1+Mr17sJndJRER1UlV+fls9yT06OhrPP/88+vfvX+NzqqT44osvMGvWLHz55ZfIzs7Gfffdh82bNxvDVUU8PDywY8cOTJgwAe+88w70ej169+6NxYsXG8MVABw/fhwAcO7cOTz//PNmn7N9+3arAxaRLelLl8Eq68HiJHciIntgdQ+Wq6srioqK4OXlhZiYGAwdOvSu4YUsYw8W2dJ/1hzBzfxi+HmqkZaVj/UvPSh3SUREdVKNPCrn2rVr+OyzzxAeHo7PPvsMkZGRaNq0KaZNm4YTJ05Uu2gikkY06cGqEyP+REQOz+qA5e7ujhEjRuCXX35BRkYGPvzwQzRu3Bjz589Hp06d0LFjR7z//vu4ePFiTdZLRHcQIZbdRajgXYRERHZC0kruvr6+ePXVV7F//36cP38eb731FoDSFcuDg4PRs2dPkzv6iKjm6PW4fRch18EiIrIL1X5UTvPmzTFz5kycPHkSx44dw1NPPYU9e/bg5ZdftkV9RHQXIsRyzyJkwCIisgdVflSOJZmZmVi7di3WrFmDI0eOAAC6du1qi48morvQi6WPyuFdhERE9kNywLp58yYSExOxZs0a7N69GzqdDi1btsSbb76JYcOGoVWrVrask4gqIJY9KkepFMAOLCIi+1ClgFVYWIgffvgBa9aswS+//AKtVgtfX1+8/PLLGDZsGCIiImqqTiKqgCgCCgV7sIiI7InVAWv48OHYtGkTcnNz4ebmhmeffRZDhw7Fo48+CqVSWZM1ElEl9KIIJcruIuQkdyIiu2B1wFq7di369euHoUOH4plnnoGbm1tN1kVEVhJROgdLKXAdLCIie2F1wMrIyDB5dAwR2Qfjo3KUvIuQiMheWLVMQ1pamuRwlZaWJqkdEVlHFMXSHiyu5E5EZDesClitWrXCCy+8gKSkJKs/eN++fRg+fDhat24tuTgiujtRBFD2qBz2YBER2Qerhgh3796NN954Aw888ACaNWuGRx55BJ07d0aLFi3g7e0NURSRnZ2NCxcu4NChQ/j999+Rnp6OyMhI7Nq1q6bPgeieVrrQqKEHi3cREhHZA6sCVkREBLZu3Ypjx44hISEBmzZtQkJCAgBAEAQApcMUABAUFISnn34aL7zwAsLCwmqmaiIyKv+oHPZgERHZhyqtgxUWFoYlS5ZgyZIlyMjIwJkzZ3Djxg0AQIMGDRAaGorAwMAaKZSILLv9qBwF52AREdkJySu5BwYGMkwR2YHSuwhLFxoVRUCvF6FQCHKXRUR0T6v2w56JSGZlyzQoy0IVe7GIiOTHgEXk4PSiCAECVMrSgMV5WERE8mPAInJwpSu53+7B0okMWEREcmPAInJw+rKFRlWGgMXnERIRyY4Bi8jBGR6VoxAMc7C4FhYRkdwYsIgcnSiW3kXIOVhERHbDqmUa3nrrrSp/sCAImDVrVpXbEVHV6I13EZb+e4l3ERIRyc+qgDVnzpwqfzADFlHtMCw0apyDxYBFRCQ7qwKWnnM6iOxW6aNyBK6DRURkRzgHi8jBGZZpuN2DxX8QERHJjQGLyMGJZZPc2YNFRGQ/JD+L8MSJE1i2bBmOHDmCnJwcs2FEQRCQkpJS7QKJqHJi2SR3lWGSO9fBIiKSnaQerB07diAiIgKbN29GYGAgzp8/j+DgYAQGBuKff/6Bu7s7evbsaetaicgCw6NylJzkTkRkNyQFrDfffBPBwcFITk5GQkICAGDGjBnYs2cP9u3bh0uXLiE2NtamhRKRZcY5WEoOERIR2QtJAevIkSMYPXo0PD09oVQqAQA6nQ4A0K1bN8TFxXGJBqJaohfFsnWw2INFRGQvJAUslUoFDw8PAED9+vXh5OSEq1evGvcHBwfj1KlTtqmQiConwvRZhAxYRESykxSwWrVqhXPnzgEoncweGhqK7777zrj/xx9/RKNGjWxTIRFVSi+KQLlnETJgERHJT1LA6t+/P9auXYuSkhIAwMSJE7Fx40a0bt0arVu3xg8//IC4uDibFkpElpXOwRLKzcHiOlhERHKTtEzDrFmzMH78eOP8qxEjRkCpVGLDhg1QKpWYOXMmRo4cacs6iagCpXcRcg4WEZE9kRSwnJyc0KBBA5Ntw4YNw7Bhw2xSFBFZT683zMHiw56JiOwFV3InqgMUvIuQiMiuWNWDFRkZCYVCgV9++QUqlQqPPPLIXdsIgoBt27ZVu0Aiqpy+bCl3FR+VQ0RkN6wKWKIomjwKR6/XQyi7Y6myNkRU80Txzh4sTnInIpKbVQFrx44dlb4nIvkYHpVj7MHiswiJiGQnaQ7Wrl27cO3atQr3X79+Hbt27ZJcFBFZTwS4kjsRkZ2RFLAiIyPx66+/Vrh/27ZtiIyMlFyUFFqtFlOnTkVgYCBcXV3RrVu3SmssLz09HbGxsahfvz48PT0xYMAAnD9/3uKxn376Kdq2bQsXFxe0bt0ay5Yts+VpEFWZKIpQCKXzHpUKgXOwiIjsgKSAdbf5VVqt1rhGVm0ZOXIkFi1ahKFDh2LJkiVQKpXo378/9uzZU2m73NxcREZGYufOnZgxYwbi4+Nx9OhR9OrVCzdu3DA5dsWKFXjxxRfRvn17LFu2DN27d8e4cePw/vvv1+SpEVWqdI57ae+VUiGwB4uIyA5YvQ7WxYsXkZqaanx/5swZi8OAN2/exIoVK9CsWTObFGiNpKQkfPPNN1iwYAEmTZoEABg+fDg6dOiAKVOmYN++fRW2Xb58Oc6dO4ekpCSEh4cDAJ544gl06NABCxcuxNy5cwEABQUFmDlzJqKiopCYmAgA+Pe//w29Xo+3334bY8aMgbe3dw2fKZE5vSgaH5OjFNiDRURkD6zuwUpISEDv3r0RGRkJQRDw7rvvIjIy0uz19NNPIykpCdOnT6/Juk0kJiZCqVRizJgxxm0uLi4YPXo09u/fj7S0tErbhoeHG8MVAISGhqJPnz5Yt26dcdv27dtx48YNjB071qT9K6+8gry8PPz44482PCMi6+lLV2kAAKgUAvQMWEREsrO6Bys2NhYdOnSAKIqIjY3FuHHj8PDDD5scIwgC6tWrh7CwMPj7+9u82IocPXoUISEh8PT0NNkeEREBADh27BiCgoLM2un1epw4cQIvvPCC2b6IiAhs3boVt27dgoeHB44ePQoA6Nq1q8lxXbp0gUKhwNGjRytcyV6r1UKr1RrfazSaqp0gUSUMc7AAQKlkDxYRkT2wOmC1bdsWbdu2BVDam9WzZ0+0aNGixgqriszMTAQEBJhtN2zLyMiw2C4rKwtarfaubdu0aYPMzEwolUr4+fmZHOfs7IwGDRpU+B0AMG/ePMTHx1t9PkRVUboOVmnCUikEroNFRGQHJE1yHzFihN2EK6B0fpRarTbb7uLiYtxfUTsAVrUtKCiAs7Ozxc9xcXGp8DsAYPr06cjJyTG+KhuyJKoqfbmbTngXIRGRfZD0sGcAOH36NBISEnD+/HlkZ2eb3VlYm4/KcXV1NRmCMygsLDTur6gdAKvaurq6oqioyOLnFBYWVvgdQGmAsxTiiGxBRPkeLAXvIiQisgOSAtaXX36JUaNGwcnJCW3atLF491xtPionICAA6enpZtszMzMBAIGBgRbb+fj4QK1WG4+rrG1AQAB0Oh2uXr1qMkxYVFSEGzduVPgdRDVNX34OFnuwiIjsgqSANWfOHHTq1Ak//fQTGjZsaOuaqiwsLAzbt2+HRqMxmeh+4MAB435LFAoFOnbsiEOHDpntO3DgAIKDg+Hh4WHyGYcOHUL//v2Nxx06dAh6vb7C7yCqafpy62CpuA4WEZFdkDQHKyMjAy+88IJdhCsAiI6Ohk6nw8qVK43btFotEhIS0K1bN+MdhBcvXsSZM2fM2h48eNAkZCUnJ+P3339HTEyMcdsjjzwCHx8ffPTRRybtP/roI7i5uSEqKqomTo3o7soe9gyU9WDxWYRERLKT1IN13333VXrXXG3r1q0bYmJiMH36dFy9ehWtWrXC559/jtTUVHz66afG44YPH46dO3eaDF+OHTsWq1atQlRUFCZNmgQnJycsWrQI/v7+eP31143Hubq64u2338Yrr7yCmJgYPPbYY9i9eze++uorvPvuu/Dx8anVcyYy0IuiyUruJbyLkIhIdpIC1qJFixATE4MnnngCDz74oK1rkuSLL77ArFmz8OWXXyI7Oxv33XcfNm/ejJ49e1bazsPDAzt27MCECRPwzjvvQK/Xo3fv3li8eDF8fX1Njh07diycnJywcOFC/PDDDwgKCsLixYsxfvz4mjw1okqVBqzS3zspFShmDxYRkewEUcJs9H/96184d+4czp49i3bt2qFp06Zmzx4UBAGbNm2yWaF1iUajgZeXF3JycswWRyWqqhbTf8TcZzpiSERTDFy+F8G+7vgg5n65yyIiqnOq8vNbUg/WiRMnIAgCmjZtitzcXJw6dcrsGMOQBRHVHFEUyxYaLX3vrFKgqIRDhEREcpMUsMo/9JmI5GPofxZQmrCcVUoGLCIiOyDpLkIisg+G8X1Dh7GzUkCxjgGLiEhukgOWTqfDN998g7i4ODzzzDM4efIkACAnJwcbN27ElStXbFYkEVlmeEyOYSV3Z5UCRQxYRESykxSwbt68iR49euC5557D2rVr8cMPP+DatWsAAHd3d4wbNw5LliyxaaFEZM4QsG73YHEOFhGRPZAUsKZNm4a//voLv/zyC86fP2+yrpRSqUR0dDS2bNlisyKJyDLDXz1DD5aTkj1YRET2QFLA+v777/Hqq6+iX79+Fu8WDAkJ4UR4olpgnOTOuwiJiOyKpICVk5ODFi1aVLi/uLgYJSUlkosiIuvcHiK8PQeLk9yJiOQnKWC1bNkSR44cqXD/1q1b0a5dO8lFEZF1DIPzCs7BIiKyK5IC1osvvojPPvsM3377rXH+lSAI0Gq1mDlzJn7++WfExcXZtFAiMmfswUK5uwgZsIiIZCdpodHx48fjr7/+wpAhQ1C/fn0AwHPPPYcbN26gpKQEcXFxGD16tC3rJCILbk9yL/3VWalAEZ9FSEQkO0kBSxAErFq1CiNGjEBiYiLOnTsHvV6Pli1bIjY29q4PWCYi2xDvmIPlpFKgqEQnZ0lERASJAcvgoYcewkMPPWSrWoioivR33kWoVKCYPVhERLKTNAdLqVRizZo1Fe7/9ttvoVQqJRdFRNYRuZI7EZFdkhSwyi8saolOp7O4PhYR2ZbewhwsnV6ETs9eLCIiOUl+FmFFAUqj0eCXX35Bw4YNJRdFRNYR73xUjqr0rzTXwiIikpfVASs+Ph5KpRJKpRKCIGDYsGHG9+Vf3t7e+PLLLzF48OCarJuIcHsdrPILjQKAlks1EBHJyupJ7hERERg7dixEUcTy5cvRr18/hISEmBwjCALq1auHLl26YODAgTYvlohM6e+Yg+WkLA1YXAuLiEheVgesJ554Ak888QQAIC8vDy+99BK6detWY4UR0d0Z7yIse88hQiIi+yBpmYaEhARb10FEEpjdRcgeLCIiuyB5krtGo0F8fDwiIiLg7+8Pf39/RERE4K233oJGo7FljURUAbOV3FWlv2EPFhGRvCQFrIyMDHTq1Anx8fHIzc1Fjx490KNHD+Tl5WHOnDno3LkzMjMzbV0rEd3BMAcLxmUaStef4yR3IiJ5SRoinDp1Ki5fvozNmzejf//+Jvt++uknxMTEYNq0afj8889tUiQRWXa7B8v0LkIuNkpEJC9JPVg///wzXnvtNbNwBZROhh83bhy2bNlS7eKIqHLmdxGWDRGyB4uISFaSAlZeXh78/f0r3N+oUSPk5eVJLoqIrGP2LEL2YBER2QVJAatdu3ZYu3YtioqKzPYVFxdj7dq1aNeuXbWLI6K7MfRglb7jMg1ERPZB8hysQYMGGRcfNSw4mpycjI8//hgnTpzAt99+a9NCicjc7R4sLtNARGRPJAWsmJgY5OXlYdq0aXjppZeM/3EXRRF+fn747LPPEB0dbdNCicicYQ7WnQuN8i5CIiJ5SQpYADBy5EgMGzYMBw8exMWLFwEAzZo1Q9euXaFSSf5YIqoCs7sI2YNFRGQXqpWEVCoVunfvju7du9uqHiKqgjvvIlQpFVAInORORCQ3yQFLq9Vi1apV2LJlC1JTUwEAzZs3R//+/fHiiy/CxcXFVjUSUQXEO+4iBEqHCdmDRUQkL0l3EV66dAlhYWEYN24cjh8/Dl9fX/j6+uL48eMYN24cwsLCcOnSJVvXSkR3sBiwlAxYRERykxSwXnnlFfzzzz9Yt24d0tPTsXPnTuzcuRPp6en49ttvcfHiRbzyyiu2rpWI7nDnECHAHiwiInsgaYhw27ZtmDBhgsU7BWNiYnDkyBEsW7as2sURUeWMdxHe2YPFOVhERLKS1IPl4eEBPz+/Cvc3atQIHh4ekosiIuuUjRBCwB09WAxYRESykhSwRo0ahdWrVyM/P99sX25uLhISEjB69OhqF0dEldOXrTSqLPc3mUOERETykzREGBYWhh9//BGhoaEYMWIEWrVqBQA4d+4cvvjiC/j4+OC+++7Dxo0bTdoNHDiw+hUTkZFOzzlYRET2SFLAGjx4sPH37777rtn+S5cuYciQIRANtzih9FEeOp1OytcRUQV0oqEHq1zA4l2ERESykxSwtm/fbus6iEgCfVmOMuvB4hwsIiJZSQpYvXr1snUdRCSBxR4slZI9WEREMpM0yZ2I7MPtSe4cIiQisicMWEQOzNIkdzWHCImIZFcnAtbNmzcxZswY+Pr6ol69eoiMjMSRI0esbn/69Gk8/vjjcHd3h4+PD55//nlcu3bN5JgzZ85gypQpCAsLg4eHBwICAhAVFYVDhw7Z+nSIrGZ5iFABLXuwiIhk5fABS6/XIyoqCmvWrMF//vMfzJ8/H1evXkXv3r1x7ty5u7a/dOkSevbsib///htz587FpEmT8OOPP6Jfv34oKioyHvfJJ59g1apV6Nq1KxYuXIiJEyciOTkZDzzwAH777beaPEWiChmHCAUOERIR2RNJk9ztSWJiIvbt24f169cbH90TGxuLkJAQzJ49G2vWrKm0/dy5c5GXl4fDhw+jadOmAICIiAj069cPq1evxpgxYwAAQ4YMwZw5c+Du7m5s+8ILL6Bt27aYM2cO+vbtW0NnSFQxQw+Wotw/lZxUAgMWEZHMbNKDlZOTI9saV4mJifD39zdZxNTX1xexsbHYtGkTtFptpe03bNiAJ5980hiuAKBv374ICQnBunXrjNu6dOliEq4AoEGDBnj44Ydx+vRpG50NUdXoLE5yV6KYc7CIiGQlOWAdOnQIjz/+ONzc3NCgQQPs3LkTAHD9+nUMGDAAO3bssFWNlTp69Cg6d+4MhcL0VCIiIpCfn4+zZ89W2DY9PR1Xr15F165dzfZFRETg6NGjd/3+y5cvo2HDhpUeo9VqodFoTF5EtmB42DPXwSIisi+SAta+ffvw0EMP4dy5cxg2bBj0+tv/MW/YsCFycnKwYsUKmxVZmczMTAQEBJhtN2zLyMiotG35Y+9sn5WVVWkP2O7du7F//34MGjSo0hrnzZsHLy8v4ysoKKjS44msZchRd05y5xAhEZG8JAWsGTNmoG3btjh16hTmzp1rtj8yMhIHDhyo8ufq9XoUFhZa9TI8hqegoABqtdrss1xcXIz7K2LYJ6X91atX8dxzz6FFixaYMmVKpec1ffp05OTkGF9paWmVHk9kLUuT3NUMWEREspM0yf3gwYOYN28e1Go1cnNzzfY3btwYly9frvLn7tq1C5GRkVYde/r0aYSGhsLV1dViL1NhYSEAwNXVtcLPMOyravu8vDw8+eSTuHXrFvbs2WM2N+tOarXaYogjqq7bk9x5FyERkT2RFLCcnJxMhgXvlJ6eftfQYUloaCgSEhKsOtYwrBcQEGAc6ivPsC0wMPCun1FRex8fH7NgVFRUhIEDB+LEiRP45Zdf0KFDB6vqJaoJOr1oMjwIlK2DxTlYRESykhSwHnjgASQmJuK1114z25eXl4eEhARJzyts1KgRRo4cWaU2YWFh2L17N/R6vclE9wMHDsDNzQ0hISEVtm3cuDF8fX0tLhaalJSEsLAwk216vR7Dhw/Htm3bsG7dOj6TkWSnF0WT4UHg9hwsURQh3LGPiIhqh6Q5WPHx8Th06BCioqLw008/AQCOHz+OTz75BF26dMG1a9cwa9YsmxZakejoaFy5cgUbN240brt+/TrWr1+Pp556yqQHKiUlBSkpKSbtn332WWzevNlkXtS2bdtw9uxZxMTEmBz76quv4ttvv8Xy5ctNloUgkotOL+KOG2jhrCzdUKwTZaiIiIgAiT1Y3bp1w5YtW/Dyyy9j+PDhAIDXX38dANCyZUts2bIF9913n+2qrER0dDQeeOABjBo1CqdOnULDhg2xfPly6HQ6xMfHmxzbp08fAEBqaqpx24wZM7B+/XpERkZi/PjxyM3NxYIFC9CxY0eMGjXKeNyHH36I5cuXo3v37nBzc8NXX31l8tnPPPMM6tWrV3MnSmSBTi+aLNEAlPZgAUCRTm/8PRER1S7JK7k/8sgjSE5OxrFjx3Du3Dno9Xq0bNkSXbp0qdVhCaVSiS1btmDy5MlYunQpCgoKEB4ejtWrV6NNmzZ3bR8UFISdO3di4sSJmDZtGpydnREVFYWFCxea9H4dO3YMALB//37s37/f7HMuXLjAgEW1rqIhQgClE915bwURkSwE0bDeAdUajUYDLy8v5OTkwNPTU+5yyIF9tCMFH+9MwfHZjxq3bT9zFaNWH8Qf0/ugkZeLjNUREdUtVfn5Xa1nEZ46dQrnz59HdnY2LOU0w/AhEdUMvWj5LkIAXKqBiEhGkgJWSkoKhg0bhqSkJIvBCgAEQWDAIqphd5uDRURE8pAUsOLi4nDy5El8+OGHePjhh+Ht7W3ruojICqXrYJluM9xFyB4sIiL5SApYe/fuxYwZM/Dqq6/auh4iqoJKJ7mzB4uISDaS7uFu2LAhvLy8bF0LEVVR6TpYnINFRGRvJAWsl156CV999RV0Op2t6yGiKtBZmuTOIUIiItlJGiIMCQmBTqfD/fffjxdeeAFBQUFQKpVmx3G1c6KaVaITobojYKmNQ4T8BxARkVwkBaxBgwYZfz9p0iSLxwiCwB4uohpWotPD6Y5Z7hwiJCKSn6SAtX37dlvXQUQSFOvFCgOWlgGLiEg2kgJWr169bF0HEUlQXKKHSsk5WERE9oZPgiVyYCV6EU4K07/GKqUCCoHLNBARyUnyo3IuX76MTz/9FEeOHEFOTg70etP/mAuCgG3btlW7QCKqWLFODyeV+cPVnZQK9mAREclIUsA6ceIEevfujYKCArRp0wYnT55Eu3btcPPmTaSnp6Nly5YICgqyda1EdIfSuwjNO6KdVQxYRERykjREOG3aNLi7uyM5ORm//fYbRFHEkiVLkJaWhm+//RbZ2dl47733bF0rEd2hWKeHk9K8B0utUqCYQ4RERLKRFLD27t2LuLg4NG3aFIqyfz0bhghjYmIwdOhQTJ482XZVEpFFlu4iBEonurMHi4hIPpICll6vh7+/PwCgfv36UCqVyMrKMu7v2LEjDh8+bJsKiahCJTo9VJYClkoBLXuwiIhkIylgtWjRAhcuXCj9AIUCLVq0wG+//Wbcv2/fPtSvX98mBRJRxYp1ejgpzIcIOQeLiEhekgLWo48+ivXr1xvfv/zyy/jkk0/Qt29f9OnTB59//jmee+45mxVJRJYV6yoYImTAIiKSlaS7CGfOnIkhQ4aguLgYTk5OeO2115CXl4cNGzZAqVRi1qxZmDFjhq1rJaI7lOjNFxoFOAeLiEhuVQ5YoihCqVSiffv2cHJyAlC65tUbb7yBN954w+YFElHFikss92CplAro9KIMFRERESBhiLCoqAg+Pj5YunRpTdRDRFVQrLe8TINKIaCYAYuISDZVDlhqtRqNGjWCWq2uiXqIqApKdKLFuwiVCgE6PYcIiYjkImmS+8iRI/HFF1+gqKjI1vUQURWULjRq/tfYSalAsY49WEREcpE0yb1jx474/vvv0b59e4wcORLNmzeHq6ur2XEDBw6sdoFEVLHCYh1cnCrqwWLAIiKSi6SANWTIEOPvZ82aZfEYQRCg0+mkVUVEViks1sNFpTTb7qQUoOVdhEREspEUsLZv327rOoioikRRRGGJDi5O5gFLqVCgRFcsQ1VERARIDFi9evWydR1EVEVFOj1EERaHCFUKASUcIiQiko2kgGWg0+lw+PBhpKamAgCaN2+OLl26QKk0/xc1EdlWYXHpEKClHiyVQkAJn0VIRCQbyQFr9erVmD59Oq5evQpRLP2XsiAI8PX1xdy5c/HCCy/YrEgiMqctLp3jaLEHS8lJ7kREcpIUsFasWIGXX34ZYWFhmDNnDkJCQgAAycnJWLFiBf7973+jqKgIL730kk2LJaLbjD1YFia5qxRcpoGISE6SAtb777+Phx9+GL/99pvxcTkAEBkZidGjR+ORRx7B/PnzGbCIalBhSWkPltriJHf2YBERyUnSQqOXL19GbGysSbgycHJywuDBg3HlypVqF0dEFSusZIjQSSmgmCu5ExHJRlLA6tSpE86ePVvh/rNnzyIsLExqTURkhcomuSsVfNgzEZGcJA0RLlu2DFFRUQgODsaYMWOMq7gXFBTg448/xrp167BlyxabFkpEpm73YFV0FyEDFhGRXKwKWPfdd5/ZNqVSiYkTJ2LKlCkIDAwEAGRkZKCkpAQBAQEYOXIkjh8/bttqicgoV1sCAHB3Nv9rrFIKKOEQIRGRbKwKWD4+PhAEwWRbgwYN0Lp1a5NtzZs3t1lhRFS53MKygOViIWBxkjsRkaysClg7duyo4TKIqKo0hcVwc1ZCqRDM9qmUXKaBiEhOkia5E5H8crUl8LDQewWwB4uISG7VelTOxYsXcf78eWRnZxtXcy9v4MCB1fl4IqpEbmEJ3NWW/worFQKK+agcIiLZSApYFy9exAsvvIDt27cDgMVwJQgCdDpd9aojogrdKiyBh4v5WnRA6RAhe7CIiOQjKWCNGDEC+/fvx7Rp09CtWzd4eXnZui4iuou7DRGW6EWIomh2gwoREdU8SXOw/vjjD0ydOhXvvvsu/vWvf6FXr14WX7Xl5s2bGDNmDHx9fVGvXj1ERkbiyJEjVrc/ffo0Hn/8cbi7u8PHxwfPP/88rl27Vmmbr7/+GoIgwN3dvbrlE0miKSyuNGABYC8WEZFMJPVgNWnSBN7e3rauRRK9Xo+oqCgcP34ckydPRsOGDbF8+XL07t0bhw8fNltK4k6XLl1Cz5494eXlhblz5yI3NxcffPABTp48iaSkJDg7O5u1yc3NxZQpU1CvXr2aOi2iu8rOL0JTHzeL+1TK0oBVohdh4VnQRERUwyT1YE2aNAmffvop8vPzbV1PlSUmJmLfvn1YvXo1Zs+ejVdeeQU7duyAUqnE7Nmz79p+7ty5yMvLw++//45x48ZhxowZWLduHY4fP47Vq1dbbPPOO+/Aw8MDTz/9tG1PhqgKbuQWoYG72uI+paL0r3YJe7CIiGQhqQcrLi4OOp0OrVu3RnR0NJo0aQKl0vSfyYIgYMKECTYpsjKJiYnw9/c3uWPR19cXsbGx+Oqrr6DVaqFWW/4hBAAbNmzAk08+iaZNmxq39e3bFyEhIVi3bh3GjBljcvy5c+ewePFifPfdd1i3bp3tT4jICqIolgaseuY9rADgZBgi5FpYRESykBSw/vzzT8yfPx+ZmZlYtmyZxWNqK2AdPXoUnTt3hkJh2hkXERGBlStX4uzZs+jYsaPFtunp6bh69Sq6du1qti8iIsLi8xRfe+01REZGon///lYHLK1WC61Wa3yv0WisakdUkVvaEhTp9GjgbjlgGRYfLebjcoiIZCEpYI0ZMwY5OTlYsWKF7HcRZmZmomfPnmbbAwICAJQ+H7GigJWZmWly7J3ts7KyTHrAfvzxR2zdurXKz1icN28e4uPjq9SGqDI3cosAAA3qWe6ddVKW/oODk9yJiOQhKWAdO3YM8fHx+Pe//23TYvR6PYqKiqw6Vq1WQxAEFBQUWBwCdHFxAQAUFBRU+BmGfXdrr1arUVRUhAkTJuCll15Cu3btrKrRYPr06Zg4caLxvUajQVBQUJU+g6i867mlPaJ37cHiYqNERLKQFLBatGhh6zoAALt27UJkZKRVx54+fRqhoaFwdXU1GX4zKCwsBAC4urpW+BmGfda0X7x4Ma5fvy6pJ0qtVlc6D4yoqjJulv7joJGXi8X9xrsIOQeLiEgWkgJWfHw8Jk2ahMGDB9u0JyY0NBQJCQlWHWsY1gsICDAO9ZVn2BYYGHjXz6iovY+PD9RqNXJycvDOO+9g7Nix0Gg0xjlUubm5EEURqampcHNzg5+fn1W1E1XXpewCeLk6wbOildzL5iTqLDxlgYiIap6kgLVr1y7Ur18fbdq0Qd++fREUFGTxLsIlS5ZU6XMbNWqEkSNHVqlNWFgYdu/eDb1ebzLR/cCBA3Bzc0NISEiFbRs3bgxfX18cOnTIbF9SUhLCwsIAANnZ2cjNzcX8+fMxf/58s2NbtGiBAQMG4Pvvv69S7URSpd8sQBPvintnlVxolIhIVpIC1n//+1/j7zdv3mzxGCkBS4ro6GgkJiZi48aNiI6OBgBcv34d69evx1NPPWUyNJeSkgIAaNmypXHbs88+i88//xxpaWnG3rht27bh7Nmzxrsg/fz88N1335l999KlS7F//36sXbvW4kR5oppyKbsAjetXHLAMK7lziJCISB6SApbejm79jo6OxgMPPIBRo0bh1KlTxpXcdTqd2XypPn36AABSU1ON22bMmIH169cjMjIS48ePR25uLhYsWICOHTti1KhRAAA3NzeLi4p+//33SEpK4oKjVOvSsvIR2abiIWn2YBERyUtSwLInSqUSW7ZsweTJk7F06VIUFBQgPDwcq1evRps2be7aPigoCDt37sTEiRMxbdo0ODs7IyoqCgsXLuTEdLJLhcU6/HMjD639K34O5u1H5djPP4aIiO4lgihKnwX7xx9/YPv27bh69SrGjh2L1q1bIz8/H2fOnEFISAgfhFwBjUYDLy8v5OTkwNPTU+5yyMH8lZGDqKV7sHHsg+jc1PIzQf++egt9F+1C4kvd0bW5Ty1XSERUN1Xl57ekZxEWFRVh4MCB6NGjB2bOnImlS5ciLS2t9AMVCjz66KO1Mv+K6F509sotAEBrv4r/AcNnERIRyUtSwJo1axY2b96Mjz76CMnJySjfCebi4oKYmBhs2rTJZkUS0W2nMjRo4u0KjwqWaABuT3LnHCwiInlIClhr167Fyy+/jDFjxsDHx3z4oW3btjh//ny1iyMic4f+ya5waNDAMMmdPVhERPKQFLCuXr1a4fP9gNKJ5/n5+ZKLIiLLCot1+DM9B12bVx6wbvdgcZI7EZEcJAWsoKAgnDlzpsL9e/fuRatWrSQXRUSWHb14E8U6EV2aWdmDxXWwiIhkISlgPffcc1ixYgX2799v3CYIpf9BX7VqFdatW4fhw4fbpkIiMtqRfBUN3Z3RtlHld68YH5XDIUIiIllIWgdr5syZ+OOPP9CzZ0+0bdsWgiBgwoQJyMrKwqVLl9C/f3/jKuhEZDu/nr6CPqH+UJT1UFVEqeQcLCIiOUnqwXJ2dsbPP/+MhIQEBAcHIzQ0FFqtFvfddx9Wr16N//u//zN7NiERVc/fV2/h/LU89Gl794eK8y5CIiJ5SV7JXRAEDBs2DMOGDbNlPURUgfWHLqG+mxN6tfG967G8i5CISF6SerCIqHYV6/TYcOQSnunUGGrV3XuHlQLvIiQikpPkHqw9e/bgs88+w/nz55GdnY07n7gjCAKOHz9e7QKJCNh8IgPXc4swOLypVccrFAIUAnuwiIjkIilgLVq0CJMnT4aLiwvatGljcbFRIrINvV7Ef3//G31C/dCmkYfV7VQKBZdpICKSiaSAtWDBAvTo0QP/93//By8vL1vXRETl/N+JDKRcy8OCmPur1E6pENiDRUQkE0lzsPLz8zF06FCGK6IalqctwbwtZ/BoO/+7Ph7nTiqFwDlYREQykRSwIiMjcfLkSVvXQkR3WPb738jOL8KsJ9tVua1SyR4sIiK5SApYy5Ytw7Zt2/DBBx8gKyvL1jUREYCDqVlYuSsFrz7SCkE+blVur1II0HEOFhGRLCQ/izAuLg7Tpk2Dr68v6tWrB09PT5MXhw+JpNMUFuO1b46hc1NvvNSrpaTP4BwsIiL5SJrk/uabb+Ldd99F48aN0bVrV4YpIhsq0enx6pqj0BQW45sxD0CllLZcnUqh4EruREQykRSwPv74Y0RFReH777+HQsG1Sols6Z0fT2PP39exelS4pKFBAxXnYBERyUZSOioqKkJUVBTDFZGNLd/xN1bvS8Wcp9rh4dZ3fyROZZS8i5CISDaSEtKTTz6J3bt327oWonvaql3nMf/nZIzv0xrPd29e7c9TcQ4WEZFsJAWs2bNn49SpUxg7diwOHz6Ma9euISsry+xFRHcniiI+2pGCd7ecxiuRLfFa39Y2+Vwl52AREclG0hysNm3aAACOHTuGFStWVHicTqeTVhXRPUKnF/H25lNYvS8V4/q0xoS+rSGUPai5utiDRUQkH8l3EdrqhwDRvSq/qAQTvz2OracuY+4zHfFcN+se5GwtJdfBIiKSjaSANWfOHBuXQXRvSb2eh5e+OoyLWflY8XxX9Gvnb/PvYA8WEZF8JAUsIpJu2+kreO3bY2jorsb3r/RAiL9HjXwP7yIkIpIPAxZRLSks1mHh1mSs2n0B/dr5Y2Hs/fB0caqx7+M6WERE8mHAIqoFf6bnYOK6Y0i9no8Z/UPx4kPBUChqdh4j7yIkIpIPAxZRDSrR6bFi13l8+NtZtPbzwP+9+hDaNKqZIcE7cQ4WEZF8GLCIasiF63mYuO4YjqfdxMu9W2J8nxA4q2rv6Qelc7AYsIiI5MCARWRjoijiqwMXMffH0/DzVGP9S93RpZlPrdehUgjQlnCSOxGRHBiwiGzoiqYQUxJPYOfZaxjarSlm9G+Lemp5/prxLkIiIvkwYBHZyM9/ZmLaxpNwUiqQMCockW38ZK1HpRBQwoVGiYhkwYBFVE252hLE//AX1h++hMfbN8LcgR3hU89Z7rJ4FyERkYwYsIiqIeVaLsZ8cQiXcwoxP/o+xHRpYjePkeJdhERE8mHAIpLo11NXMOHbY2jk5YIfXn0ILX3d5S7JhFLJuwiJiOTCgEUkwdqki5jx3Uk82s4fC2PD4C7TRPbKsAeLiEg+9vdTgcjOfbwzBe/9dAYjujfD7Kfa1/iK7FLxLkIiIvkwYBFVwZd//IP3fjqD/0S2wuuPhtjNfCtL2INFRCSf2ltWmsjB/fxnJt7c9CdGPtjc7sMVwLsIiYjkxIBFZIW/r97CxHXH0b9DAN58sp3dhyuA62AREcmJAYvoLvKLSvDyV0cQWN8V86Pvs9s5V3fiswiJiORTJwLWzZs3MWbMGPj6+qJevXqIjIzEkSNHrG5/+vRpPP7443B3d4ePjw+ef/55XLt2zeKxKSkpeO655+Dn5wdXV1e0bt0aM2fOtNWpkB364JezSMvOx8fDOsv22BspOAeLiEg+jvPTogJ6vR5RUVE4fvw4Jk+ejIYNG2L58uXo3bs3Dh8+jNatW1fa/tKlS+jZsye8vLwwd+5c5Obm4oMPPsDJkyeRlJQEZ+fbK3IfO3YMvXv3RuPGjfH666+jQYMGuHjxItLS0mr6NEkmRy5mI2HfBcx4oi1a+XnIXU6VlK6DxbsIiYjk4PABKzExEfv27cP69esRHR0NAIiNjUVISAhmz56NNWvWVNp+7ty5yMvLw+HDh9G0aVMAQEREBPr164fVq1djzJgxAEqD3PPPP4/Q0FBs374drq6uNXtiJDudXsSMjSdxX2MvjOrRXO5yqow9WERE8nH4IcLExET4+/tj4MCBxm2+vr6IjY3Fpk2boNVqK22/YcMGPPnkk8ZwBQB9+/ZFSEgI1q1bZ9y2detW/Pnnn5g9ezZcXV2Rn58PnU5n+xMiu7Hh8CWcuXwLbw3oAJXS8f6q8C5CIiL5ON5PjTscPXoUnTt3hkJheioRERHIz8/H2bNnK2ybnp6Oq1evomvXrmb7IiIicPToUeP73377DQCgVqvRtWtX1KtXD25ubhg8eDCysrIqrVGr1UKj0Zi8yL4VFOmw6NezePK+ANwfVF/uciRhDxYRkXwcPmBlZmYiICDAbLthW0ZGRqVtyx97Z/usrCxjD9i5c+cAlA4/hoaGIjExEVOnTsWGDRvw1FNPQRQr/kE2b948eHl5GV9BQUHWnyDJ4qs//sH1XC0mP9ZG7lIkUyoElOg4B4uISA52NQdLr9ejqKjIqmPVajUEQUBBQQHUarXZfhcXFwBAQUFBhZ9h2He39mq1Grm5uQCA8PBwfPXVVwCAZ599Fm5ubpg+fTq2bduGvn37Wvye6dOnY+LEicb3Go2GIcuOFZXo8cme83imU2M0a1BP7nIkUykE6EVArxcdZmkJIqK6wq56sHbt2gVXV1erXsnJyQAAV1dXi/OsCgsLjfsrYthnTXvDr0OGDDE57rnnngMA7Nu3r8LvUavV8PT0NHmR/dp0LB1XNFqM6RksdynVoiwLVbpKeleJiKhm2FUPVmhoKBISEqw61jCsFxAQYBzqK8+wLTAw8K6fUVF7Hx8fY++W4XP8/f1NjvPz8wMAZGdnW1U32TdRFLFy13n0beuH1v6OtSzDnVTKsoClF+GklLkYIqJ7jF0FrEaNGmHkyJFVahMWFobdu3dDr9ebTHQ/cOAA3NzcEBISUmHbxo0bw9fXF4cOHTLbl5SUhLCwMOP7Ll26YNWqVUhPTzc5zjDHy9fXt0p1k33af/4Gzl3NxVsDOshdSrUpy/4+cKI7EVHts6shQimio6Nx5coVbNy40bjt+vXrWL9+PZ566imT+VUpKSlISUkxaf/ss89i8+bNJouFbtu2DWfPnkVMTIxx24ABA6BWq5GQkAB9ucUbP/nkEwBAv379bH5uVPu+PZiGYN96eCDYR+5Sqk1lGCLk8wiJiGqdXfVgSREdHY0HHngAo0aNwqlTp4wruet0OsTHx5sc26dPHwBAamqqcduMGTOwfv16REZGYvz48cjNzcWCBQvQsWNHjBo1ynhco0aNMHPmTLz55pt4/PHH8fTTT+P48eNYtWoVhgwZgvDw8Fo5X6o5N/OL8NOflzHp0RCHeJjz3RjmYJVwNXciolrn8AFLqVRiy5YtmDx5MpYuXYqCggKEh4dj9erVaNPm7rfYBwUFYefOnZg4cSKmTZsGZ2dnREVFYeHChWZ3F77xxhvw9vbGsmXL8Nprr5mELnJ8G4+kQxRFPNu5idyl2ISxB4tDhEREtU4QK1vAiWqERqOBl5cXcnJyeEehHYlauhtNfdzw0bAucpdiEzvPXsOIz5Kwb9ojCKzPRzsREVVXVX5+O/wcLCJbOH8tF39laDAgrOK7Th0Ne7CIiOTDgEUEYPOJTNRzVqJ3Gz+5S7GZ23OwGLCIiGobAxYRgM0nMtCvnT9c6tCCUbd7sDjJnYiotjFg0T0v+fItnL2SiyfvqzvDgwB7sIiI5MSARfe8LScz4eGiwsMhDeUuxaZUhoVGuQ4WEVGtY8Cie962M1cQ2cYPalXdGR4Eyj2LkD1YRES1jgGL7mmXcwrxZ7oGfdrWncntBoZnEXKIkIio9jFg0T3t9zNXoRCAXiF171mS7MEiIpIPAxbd034/cwVdm/mgvpuz3KXYnIqPyiEikg0DVh0iiiLWJl3E5/tS8ffVW+Ai/ZUrLNZhz9/X6+TwIMAeLCIiOTn8swjptvPX8zB940njez8PNR5s2QAPtmyIsKb1EdywHlRKZmqD/Sk3UFisr7MBy3gXIQMWEVGtY8CqQ1r6umP/9Efg5qzCsbSb2Pf3dexNuY5NxzMgioCLkwJtAzzRPtATLRq6o0VDNzRvUA9BPm5wugeD156/ryPAywUtfd3lLqVGGHuwuEwDEVGtY8CqYwK8Sh/q2yvE1zhxW1NYjFMZGvyZnoO/MjQ4eCEb6w9dgrakdG6OUiHA30MNP08X+Huq4e/pAn9PF/h6qOHt5gwvVyfUd3OCl2vpq66sdn7kYjYiWvhAEAS5S6kRKi40SkQkGwase4CnixMeCG6AB4IbGLfp9SIuawqRej0PF27kIfNmIa5oCnHllhZJF7JwRVOI7Pxii5+nVing6eoEN2cl3JxVZb8qje9dnZWo56yEq7MKLk4KqFVKOKsUUCsVpb+qSn91VingrFRA7aSEc7l9TkoFlAoBTkqh7NfS9yqFYNMwlJVXhIgWPjb7PHujVHIOFhGRXBiw7lEKhYDA+q4IrO+KB1tZXsG8qEQPTWExbuYXI6egGDkFRcgpKH2vKShBfnEJCop0yNPqUFBcgjytDtl5BcgvLkG+Vof8Ih0KinUoKtGjSKe3yQ96Q9C6M4SpFAqolKX7TH5vcpwCTgoBqrI2mTmF8K6Ddw8a8C5CIiL5MGBRhZxVCjR0V6Ohu9omn6fTi6Vhq0QPbYkO2rLgZdhWpNNDW6xHiV6PEp2IEr1o+nud3vRXvQidXkRxWXgr1onQ6fVlv5a2Nfy+/DHaktLfd2vhg4cqCJd1Ae8irJxeL+JWYQmy84uQnV+Em/nFuKUtQWGRDoUlOhSU/QOhoFiHwiIddKIInb60nV4UoRNFiGLp9S39vQgBAgQBUAgCFIZfFbd/L5TfLqDsvQClwvRYZdmxSkNbhQBl2bHGY8p6dJXC7WNMPqvcZxuPK9unVAjljin3WYry9Zl+v6LsM4Sy40vbwGJdlj6b6F7DgEW1RqkQ4OqshKuzEoCT3OXUeff6XYR6vYhL2QU4e+UW/snKR3p2AdJv5iPjZiEycwqQnV9cYfh0Virg4qQo/fPqpIRapYRKKZiFoDtDBQDoRRF6femvolj2XhShF0uXUtEbt5XWaAhnhu06vXlw0+lvH28Id+XfO8L/xZWFt9uBslw4VJiHt8qCX/nwWBooYRb8ygdSQ+gTjP8DCGW/EYzvYXxvts+YGQWLxxs+z3zf7bApVPK9t79HMGkPS7VY8b0o9zlV+d47a3UksV2DbNZBIAUDFlEdVdaBdU/0YOn1IlKu5eLIxWwc+ecm/srMwd9Xc1FYXDo86uKkQOOyIfH2gZ7o184fPvWc4e3mDG83J3iX/d7DRQUXJ6Wx989RWAxohmBXFs5Kt5uGM50xoN0+pnxAvB3wYPysO8OdMfyJollAvL2tXNDUi9CVhU2Ttnd8tjX1Gz7bsN3yd4soKn+e+tJrU3rhABFi2TU0bjJeU8P7O/fB4r47Pkc0/6zyzSv73tvfU/G+yr63/J8L0/aVfe/td5ZqcsReyH5t/RmwiMj2BKF0Hlpd7cFKy8rHzrPXsCP5GpIu3ICmsASCALTx90DHxl4YcH9jtPZ3R4i/BwK8XBzyB4S1DD02SgioIzf5Ejk8BiyiOkypEKDT1Z1J7mcua/DDsQz88tdlpFzLg1IhoEszb7z4cDA6N/XG/UFe8HDh8DMRyY8Bi6gOqws9WFc0hUg8fAk/HMtA8pVb8HJ1wmPt/THp0Tbo0bohPBmoiMgOMWAR1WFKheCQc7BEUcS+lBv46o9/sPXUFTgrFXi0vT+mPN4GD7f2hbPq3nvyABE5FgYsojpMpVQ4VA9WsU6P74+m4+OdKUi5lofWfu6Y/VQ7PNOpMYf+iMihMGAR1WGO0oNVrNNj45FL+N/2FFzMysej7fwx95mOdfpRRkRUtzFgEdVh9j4Hq6hEjw1HLuF/2//GpewCPNGhET4e1gXtAj3lLo2IqFoYsIjqMKVCQIkd3kVYVKLH+sNpWL49BRk5BejfIQCfjOiK0EYMVkRUNzBgEdVh9ZxVyC/SVeszsvOK8MqaI+jfMQDDHmhWrc/Sluiw7tAlfLT9b2RqChHVMQAJfcIR4u9Rrc8lIrI3DFhEdZiHiwqawmLJ7dNvFmBUQhLOXslFIy8XyQGrsFiHbw+m4aMdKbh6qxBP3R+I/0S2QmsGKyKqoxiwiOowDxcVbhWWSGp7MDULL315GC5OSrQP9ERWXlGVPyO/qARrDlzEyl3ncT1XiwFhjfGfR1qhpa+7pJqIiBwFAxZRHebh4oSrtwqr1KZEp8dHO1KwZNs5dGnmjY+GdcFney7gi/2pyNWWwF199/9s5BQU48v9qfh0zwXcKizBM50a4+XeLRHMYEVE9wgGLKI6zMNFhZRr1vdgHf4nG/H/9xf+TM/By71b4rW+IXBSKjCkW1N8suc8PvglGXP+1b7C9n9l5OCrP/7B90czoBNFDOoahLhewWji7WaL0yEichgMWER1mJerE27m330O1p/pOfjf9r/x05+X0TbAExtefhCdmnob9zeu74opj4Xirc2nIAjACz1aoHF9V9wqLMGpTA32p1zHz39dLp2r5emCl3u3xOCIIPh5uNTk6RER2S0GLKI6LMjHDZk5BSgq0Zs9XianoBi/nbqCbw5exMHUbDSu74qFMffj6U6NoVSYL+45qkdz6EURC35JRsLeVJN9Hi4q9Gvrj8mPhSKyjS9USj7KhojubQxYRHVY8wb1oBeBlGu5CPH3wOlMDQ5cyMLuc9ew9+/rKNaJeCDYBx8P64y+bf0rDUaCIODFh4MRGx6EP1Ju4EZeEdzVKrRp5IGWvu4WQxkR0b1KEEXRfpd5rqM0Gg28vLyQk5MDT08urEg1p7BYh25zt8FZpUBhkQ63tCVwVinQpak3Hm3vjyc6BKCRF4fxiIisUZWf3+zBIqrDXJyU+HREV3x/LB0BXq7o2swb9wfVh4uTUu7SiIjqNAYsojqua3MfdG3uI3cZRET3FM5EJSIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG6sTAevmzZsYM2YMfH19Ua9ePURGRuLIkSNWtz99+jQef/xxuLu7w8fHB88//zyuXbtmdlxmZibGjBmDFi1awNXVFS1btsTEiRNx48YNW54OEREROTiHXwdLr9fj4YcfxvHjxzF58mQ0bNgQy5cvR1paGg4fPozWrVtX2v7SpUvo1KkTvLy8MG7cOOTm5uKDDz5A06ZNkZSUBGdnZwBAbm4uOnTogLy8PIwdOxZBQUE4fvw4VqxYgfbt2+Pw4cNQKKzLq1wHi4iIyPHcU+tgJSYmYt++fVi/fj2io6MBALGxsQgJCcHs2bOxZs2aStvPnTsXeXl5OHz4MJo2bQoAiIiIQL9+/bB69WqMGTMGAPDDDz/gn3/+webNmxEVFWVs7+Pjg7feegvHjx9Hp06daugsiYiIyJE4/BBhYmIi/P39MXDgQOM2X19fxMbGYtOmTdBqtZW237BhA5588kljuAKAvn37IiQkBOvWrTNu02g0AAB/f3+T9gEBAQAAV1fXap8LERER1Q0OH7COHj2Kzp07mw3PRUREID8/H2fPnq2wbXp6Oq5evYquXbua7YuIiMDRo0eN73v27AmFQoHx48fjjz/+wKVLl7Blyxa8++67ePrppxEaGmq7kyIiIiKH5vABKzMz09iLVJ5hW0ZGRqVtyx97Z/usrCxjD1i7du2wcuVKnDp1Ct27d0dQUBCioqLQp08frF+/vtIatVotNBqNyYuIiIjqLruag6XX61FUVGTVsWq1GoIgoKCgAGq12my/i0vpA2wLCgoq/AzDvru1N+xv3LgxIiIi0L9/fzRr1gy7d+/G0qVL0bBhQ3zwwQcVfs+8efMQHx9v1XkRERGR47OrgLVr1y5ERkZadezp06cRGhoKV1dXi/OsCgsLAVQ+N8qwz5r2e/fuxZNPPok//vjDOKT49NNPw9PTE/Hx8XjhhRfQrl07i98zffp0TJw40fheo9EgKCjImtMkIiIiB2RXASs0NBQJCQlWHWsY1gsICDAO9ZVn2BYYGHjXz6iovY+Pj7H3asWKFfD39zebr/Wvf/0Lc+bMwb59+yoMWGq12mIvGREREdVNdhWwGjVqhJEjR1apTVhYGHbv3g29Xm8y0f3AgQNwc3NDSEhIhW0bN24MX19fHDp0yGxfUlISwsLCjO+vXLkCnU5ndlxxcTEAoKSkpEp1ExERUd1lVwFLiujoaCQmJmLjxo3GdbCuX7+O9evX46mnnjLpOUpJSQEAtGzZ0rjt2Wefxeeff460tDTjsN22bdtw9uxZTJgwwXhcSEgItm7dih07dqB3797G7WvXrgWAKq2BZVjblZPdiYiIHIfh57Y1a7Q7/EruOp0ODz30EP7880+TldwvXryIgwcPok2bNsZjmzdvDgBITU01bktLS0OnTp1Qv359jB8/Hrm5uViwYAGaNGmCgwcPGgNacnIyunTpAkEQ8Oqrr6JZs2bYuXMn1q5di379+mHr1q1W13zp0iXOwSIiInJQaWlpaNKkSaXHOHzAAoDs7GxMnjwZ33//PQoKChAeHo4PPvjAbL6UpYAFAH/99RcmTpyIPXv2wNnZGVFRUVi4cKHZoqLJycl44403cODAAVy+fBmBgYGIiYlBfHw83NzcrK5Xr9cjIyMDHh4eEARB0jlXxDCBPi0tjY/huQteK+vxWlmP18p6vFbW47WyXk1eK1EUcevWLQQGBt718Xh1ImDRbXzOofV4razHa2U9Xivr8VpZj9fKevZyrRx+oVEiIiIie8OARURERGRjDFh1jFqtxuzZs7nulhV4razHa2U9Xivr8VpZj9fKevZyrTgHi4iIiMjG2INFREREZGMMWEREREQ2xoBFREREZGMMWEREREQ2xoDlILRaLaZOnYrAwEC4urqiW7du+PXXX61qm56ejtjYWNSvXx+enp4YMGAAzp8/X8MVy0fqtUpOTsaECRPw4IMPwsXFBYIgmK36X9dIvVYbN27EoEGDEBwcDDc3N7Rp0wavv/46bt68WfNFy0Tqtfruu+/w2GOPITAwEGq1Gk2aNEF0dDT+/PPPWqhaHtX571V5/fr1gyAI+M9//lMDVdoHqddqzpw5EATB7OXi4lILVcujun+uvv32W3Tv3h316tVD/fr18eCDD+L333+vuYJFcgiDBw8WVSqVOGnSJHHFihVi9+7dRZVKJe7evbvSdrdu3RJbt24t+vn5ie+//764aNEiMSgoSGzSpIl4/fr1Wqq+dkm9VgkJCaJCoRA7dOgghoWFiQDECxcu1E7RMpF6rRo0aCB27NhRnDVrlrhq1Spx3LhxorOzsxgaGirm5+fXUvW1S+q1io+PFwcNGiS+99574ieffCK+8847YnBwsOjq6ioeO3aslqqvXVKvVXkbNmwQ69WrJwIQX3nllRqsVl5Sr9Xs2bNFAOJHH30kfvnll8bXmjVraqny2ledP1ezZ88WBUEQY2JixI8//lhctmyZGBcXJ37xxRc1Vi8DlgM4cOCACEBcsGCBcVtBQYHYsmVLsXv37pW2ff/990UAYlJSknHb6dOnRaVSKU6fPr3GapZLda7VjRs3RI1GI4qiKC5YsKDOB6zqXKvt27ebbfv8889FAOKqVatsXarsqnOtLLl8+bKoUqnEuLg4W5ZpF2xxrQoKCsTmzZuLb731Vp0OWNW5VoaAde3atZou0y5U51rt379fFARBXLRoUU2XaYJDhA4gMTERSqUSY8aMMW5zcXHB6NGjsX//fqSlpVXaNjw8HOHh4cZtoaGh6NOnD9atW1ejdcuhOtfKx8cHHh4etVGmXajOterdu7fZtmeeeQYAcPr0aZvXKrfqXCtL/Pz84ObmVieHVG1xrebPnw+9Xo9JkybVZKmys8W1EkURGo0GYh1f0rI61+rDDz9Eo0aNMH78eIiiiNzc3NoomXOwHMHRo0cREhJi9tDKiIgIAMCxY8csttPr9Thx4gS6du1qti8iIgIpKSm4deuWzeuVk9RrdS+y9bW6fPkyAKBhw4Y2qc+e2OJa3bx5E9euXcPJkyfx4osvQqPRoE+fPjVRrqyqe60uXryI9957D++//z5cXV1rqky7YIs/V8HBwfDy8oKHhweGDRuGK1eu1ESpsqvOtdq2bRvCw8OxdOlS+Pr6wsPDAwEBAfjvf/9bkyVDVaOfTjaRmZmJgIAAs+2GbRkZGRbbZWVlQavV3rVtmzZtbFitvKReq3uRra/V+++/D6VSiejoaJvUZ09sca0eeOABJCcnAwDc3d3xxhtvYPTo0bYt1A5U91q9/vrr6NSpEwYPHlwj9dmT6lwrb29v/Oc//0H37t2hVquxe/du/O9//0NSUhIOHTpkFkQcndRrlZ2djevXr2Pv3r34/fffMXv2bDRt2hQJCQl49dVX4eTkhLi4uBqpmQHLARQUFFh8ppLhbpGCgoIK2wGQ1NZRSb1W9yJbXqs1a9bg008/xZQpU9C6dWub1WgvbHGtEhISoNFocP78eSQkJKCgoAA6nQ4KRd0aSKjOtdq+fTs2bNiAAwcO1Fh99qQ612r8+PEm75999llERERg6NChWL58OaZNm2bbYmUm9VoZhgNv3LiBb775BoMGDQIAREdHo2PHjnjnnXdqLGDVrb/ZdZSrqyu0Wq3Z9sLCQuP+itoBkNTWUUm9VvciW12r3bt3Y/To0Xjsscfw7rvv2rRGe2GLa9W9e3c89thjePnll/HLL7/gq6++wvTp021eq9ykXquSkhKMGzcOzz//vMmc0brM1v+9eu6559CoUSP89ttvNqnPnlT356CTk5NJ77pCocCgQYNw6dIlXLx4sQYqZsByCAEBAcjMzDTbbtgWGBhosZ2Pjw/UarWkto5K6rW6F9niWh0/fhz/+te/0KFDByQmJkKlqpud4rb+c+Xt7Y1HHnkEX3/9tU3qsydSr9UXX3yB5ORkxMXFITU11fgCgFu3biE1NRX5+fk1VrccauK/V0FBQcjKyqp2bfamOj8HXVxc0KBBAyiVSpN9fn5+AEqHEWsCA5YDCAsLw9mzZ6HRaEy2G7rRw8LCLLZTKBTo2LEjDh06ZLbvwIEDCA4OrnN3zUm9Vvei6l6rlJQUPP744/Dz88OWLVvg7u5eU6XKrib+XBUUFCAnJ8cW5dkVqdfq4sWLKC4uRo8ePdCiRQvjCygNXy1atMDWrVtrtPbaZus/V6IoIjU1Fb6+vrYq0W5U5+dgWFgYrl27hqKiIpN9hnlbNXa9anVRCJLkjz/+MFv/o7CwUGzVqpXYrVs347Z//vlHPH36tEnb9957TwQgHjx40LjtzJkzolKpFKdOnVrzxdey6lyr8u6FdbCqc60yMzPF4OBgMTAwsE5fI4PqXKsrV66Yfd6FCxdEDw8P8eGHH665omUi9VqdPn1a/O6778xeAMT+/fuL3333nZiRkVGr51LTqvPn6urVq2af97///U8EUOvrPdWG6lyrxYsXiwDElStXGrcVFBSIwcHBYrt27WqsZgYsBxETEyOqVCpx8uTJ4ooVK8QHH3xQVKlU4s6dO43H9OrVS7wzM2s0GrFly5ain5+fOH/+fHHx4sViUFCQGBgYaPEvaF0g9VrdvHlTfPvtt8W3335bfPzxx0UA4uuvvy6+/fbb4rJly2r7NGqF1Gt1//33iwDEKVOmmKwi/eWXX4pbt26t7dOoFVKvlZ+fnzhkyBDx/fffF1euXClOnjxZ9PHxEV1cXMS9e/fW9mnUCqnXyhLU4YVGRVH6tXJ1dRVHjhwpLly4UPzf//4nDhkyRBQEQQwLCxPz8vJq+zRqhdRrlZ+fL7Zv3150cnISJ02aJC5dulQMDw8XlUqluGXLlhqrlwHLQRQUFIiTJk0SGzVqJKrVajE8PFz8+eefTY6p6D9YaWlpYnR0tOjp6Sm6u7uLTz75pHju3LnaKr3WSb1WFy5cEAFYfDVr1qwWz6D2SL1WFV0nAGKvXr1q8Qxqj9RrNXv2bLFr166it7e3qFKpxMDAQHHw4MHiiRMnarP8WlWd/17dqa4HLKnX6sUXXxTbtWsnenh4iE5OTmKrVq3EqVOnGp9GURdV58/VlStXxBEjRog+Pj6iWq0Wu3XrZtbW1gRRrOPLvxIRERHVMk5yJyIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiIiIiG2PAIiIiIrIxBiwiuuc0b94cI0eOlLsMM2PHjkW/fv2q1Objjz9G06ZNodVqa6gqIpKCAYuI6qR9+/Zhzpw5uHnzptylWOXChQv45JNPMGPGjCq1GzlyJIqKirBixYoaqoyIpGDAIqI6ad++fYiPj7cYsJKTk7Fq1araL6oSS5YsQYsWLRAZGVmldi4uLhgxYgQWLVoEPlqWyH4wYBHRPUetVsPJyUnuMoyKi4vx9ddfIzY2VlL72NhY/PPPP9i+fbuNKyMiqRiwiKjOmTNnDiZPngwAaNGiBQRBgCAISE1NBWA+B2v16tUQBAF79uzBuHHj4Ovri/r16yMuLg5FRUW4efMmhg8fDm9vb3h7e2PKlClmvUV6vR4ffvgh2rdvDxcXF/j7+yMuLg7Z2dl3rXfPnj24fv06+vbta7Zv2bJlaN++Pdzc3ODt7Y2uXbtizZo1Jsd06dIFPj4+2LRpUxWvFBHVFJXcBRAR2drAgQNx9uxZrF27FosXL0bDhg0BAL6+vpW2e/XVV9GoUSPEx8fjjz/+wMqVK1G/fn3s27cPTZs2xdy5c7FlyxYsWLAAHTp0wPDhw41t4+LisHr1aowaNQrjxo3DhQsX8N///hdHjx7F3r17K+0x27dvHwRBQKdOnUy2r1q1CuPGjUN0dDTGjx+PwsJCnDhxAgcOHMBzzz1ncmznzp2xd+/eql4qIqopIhFRHbRgwQIRgHjhwgWzfc2aNRNHjBhhfJ+QkCACEB977DFRr9cbt3fv3l0UBEF86aWXjNtKSkrEJk2aiL169TJu2717twhA/Prrr02+5+eff7a4/U7Dhg0TGzRoYLZ9wIABYvv27e9ypqXGjBkjurq6WnUsEdU8DhESEZUZPXo0BEEwvu/WrRtEUcTo0aON25RKJbp27Yrz588bt61fvx5eXl7o168frl+/bnx16dIF7u7ud50bdePGDXh7e5ttr1+/Pi5duoSDBw/etXZvb28UFBQgPz/fmlMlohrGgEVEVKZp06Ym7728vAAAQUFBZtvLz606d+4ccnJy4OfnB19fX5NXbm4url69etfvFi3cATh16lS4u7sjIiICrVu3xiuvvFLhMKChffmASETy4RwsIqIySqXS6u3lA5Fer4efnx++/vpri+3vNverQYMGFifDt23bFsnJydi8eTN+/vlnbNiwAcuXL8ebb76J+Ph4k2Ozs7Ph5uYGV1fXSr+LiGoHAxYR1Um12ZPTsmVL/Pbbb+jRo4ekgBMaGoqvv/4aOTk5xl4zg3r16mHQoEEYNGgQioqKMHDgQLz77ruYPn06XFxcjMdduHABbdu2rfa5EJFtcIiQiOqkevXqAUCtrOQeGxsLnU6Ht99+22xfSUnJXWvo3r07RFHE4cOHTbbfuHHD5L2zszPatWsHURRRXFxssu/IkSN48MEHpZ0AEdkce7CIqE7q0qULAGDmzJkYPHgwnJyc8NRTTxmDly316tULcXFxmDdvHo4dO4ZHH30UTk5OOHfuHNavX48lS5YgOjq6wvYPPfQQGjRogN9++w2PPPKIcfujjz6KRo0aoUePHvD398fp06fx3//+F1FRUfDw8DAed/jwYWRlZWHAgAE2PzcikoYBi4jqpPDwcLz99tv4+OOP8fPPP0Ov1+PChQs1ErCA0ocud+nSBStWrMCMGTOgUqnQvHlzDBs2DD169Ki0rbOzM4YOHYr169dj7ty5xu1xcXH4+uuvsWjRIuTm5qJJkyYYN24c3njjDZP269evR9OmTU3CGRHJSxAt3bpCRES16vz58wgNDcVPP/2EPn36WN1Oq9WiefPmmDZtGsaPH1+DFRJRVXAOFhGRHQgODsbo0aPx3nvvValdQkICnJyc8NJLL9VQZUQkBXuwiIiIiGyMPVhERERENsaARURERGRjDFhERERENsaARURERGRjDFhERERENsaARURERGRjDFhERERENsaARURERGRjDFhERERENsaARURERGRj/w+rFP6G77z2ygAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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LMdrZTleK8vZyrXiJHciIiIiK2MPFhEREZGVMWARERERWRkDFhEREZGVMWARERERWRkDlp3QarWYNm0agoOD4eLigi5duuDXX3+1qO2VK1cQFxcHb29veHp6on///khOTq7hipUj91qdOXMGEydOxAMPPABnZ2cIgmDy3Mq6Ru61+vbbbzFo0CCEhobC1dUVLVu2xCuvvIKsrKyaL1ohcq/Vd999h0cffRTBwcHQaDRo2LAhYmJi8Oeff9ZC1cqozr9X5fXp0weCIOD//u//aqBK2yD3Ws2dOxeCIJi8nJ2da6FqZVT379U333yDrl27ws3NDd7e3njggQfw22+/1VzBEtmFwYMHSw4ODtLkyZOlFStWSF27dpUcHByknTt3VtouNzdXatGihRQQECC988470qJFi6SQkBCpYcOG0s2bN2up+tol91olJiZKKpVKatu2rRQRESEBkC5cuFA7RStE7rWqV6+e1K5dO2n27NnSypUrpfHjx0tOTk5SeHi4dPv27VqqvnbJvVYJCQnSoEGDpLffflv6+OOPpTfffFMKDQ2VXFxcpKNHj9ZS9bVL7rUqb/369ZKbm5sEQHrppZdqsFplyb1Wc+bMkQBIH3zwgfTFF18YXqtXr66lymtfdf5ezZkzRxIEQYqNjZU+/PBDadmyZVJ8fLz0+eef11i9DFh2YN++fRIAacGCBYZtBQUFUrNmzaSuXbtW2vadd96RAEj79+83bDt16pSkVqulGTNm1FjNSqnOtbp165aUk5MjSZIkLViwoM4HrOpcq23btpls++yzzyQA0sqVK61dquKqc63MuXr1quTg4CDFx8dbs0ybYI1rVVBQIDVp0kR6/fXX63TAqs610gesGzdu1HSZNqE612rv3r2SIAjSokWLarpMIxwitANJSUlQq9UYO3asYZuzszPGjBmDvXv3IjU1tdK2kZGRiIyMNGwLDw9Hr169sHbt2hqtWwnVuVa+vr7w8PCojTJtQnWuVc+ePU22Pf300wCAU6dOWb1WpVXnWpkTEBAAV1fXOjmkao1r9e6770IURUyePLkmS1WcNa6VJEnIycmBVMeXtKzOtXr//fdRv359TJgwAZIkIS8vrzZK5hwse3DkyBGEhYWZPLQyKioKAHD06FGz7URRxPHjx9G5c2eTfVFRUTh//jxyc3OtXq+S5F6re5G1r9XVq1cB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fYcPH8YDDzwg7wSIyOrYg0VEdVKnTp0AALNmzcLgwYPh6OiIJ5980hC8rKlHjx6Ij4/H/PnzcfToUTzyyCNwdHTEuXPnsG7dOixZsgQxMTEVtn/wwQdRr149bNmyBQ8//LBh+yOPPIL69eujW7duCAwMxKlTp/Cf//wH/fr1g4eHh+G4Q4cOISMjA/3797f6uRGRPAxYRFQnRUZG4o033sCHH36In3/+GaIo4sKFCzUSsIDShy536tQJK1aswMyZM+Hg4IAmTZpg+PDh6NatW6VtnZycMGzYMKxbtw7z5s0zbI+Pj8dXX32FRYsWIS8vDw0bNsT48ePx6quvGrVft24dGjVqZBTOiEhZgmTu1hUiIqpVycnJCA8Px08//YRevXpZ3E6r1aJJkyaYPn06JkyYUIMVElFVcA4WEZENCA0NxZgxY/D2229XqV1iYiIcHR3xwgsv1FBlRCQHe7CIiIiIrIw9WERERERWxoBFREREZGUMWERERERWxoBFREREZGUMWERERERWxoBFREREZGUMWERERERWxoBFREREZGUMWERERERWxoBFREREZGX/DwQPvx/OxlN4AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/Userdocs/NML2_examples/SingleNeuron.ipynb b/_sources/Userdocs/NML2_examples/SingleNeuron.ipynb new file mode 100644 index 00000000..4b28d5f2 --- /dev/null +++ b/_sources/Userdocs/NML2_examples/SingleNeuron.ipynb @@ -0,0 +1,476 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Interactive single Izhikevich neuron NeuroML example\n", + "\n", + "To run this interactive Jupyter Notebook when viewing the online NeuroML documentation (e.g. via Binder or Google Colab), please click on the rocket icon 🚀 in the top panel. For more information, please see {ref}`how to use this documentation `.\n", + "\n", + "This notebook creates a simple model in [NeuroML version 2](https://docs.neuroml.org/Userdocs/NeuroMLv2.html). It adds a [simple spiking neuron model](https://docs.neuroml.org/Userdocs/Schemas/Cells.html#schema-izhikevich2007cell) to a [population](https://docs.neuroml.org/Userdocs/Schemas/Networks.html#schema-population) and then the population to a [network](https://docs.neuroml.org/Userdocs/Schemas/Networks.html#network). Then we create a [LEMS simulation file](https://docs.neuroml.org/Userdocs/LEMSSimulation.html) to specify how to to a simulate the model, and finally we execute it using [jNeuroML](https://docs.neuroml.org/Userdocs/Software/jNeuroML.html#jneuroml). The results of that simulation are plotted below.\n", + "\n", + "
\n", + "\"NeuroML\n", + "
\n", + "\n", + "See also a {ref}`more detailed introduction to NeuroML and LEMS using this example `. \n", + "\n", + "## 1) Initial setup and library installs\n", + "\n", + "Please uncomment the line below if you use the Google Colab (it does not include these packages by default)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#%pip install pyneuroml neuromllite NEURON" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from neuroml import NeuroMLDocument\n", + "import neuroml.writers as writers\n", + "from neuroml.utils import component_factory\n", + "from neuroml.utils import validate_neuroml2\n", + "from pyneuroml import pynml\n", + "from pyneuroml.lems import LEMSSimulation\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2) Declaring the NeuroML model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a NeuroML document\n", + "\n", + "This is the container document to which the cells and the network will be added. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "nml_doc = component_factory(NeuroMLDocument, id=\"IzhSingleNeuron\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the Izhikevich cell and add it to the model\n", + "\n", + "The [Izhikevich model](https://www.izhikevich.org/publications/spikes.htm) is a simple, 2 variable neuron model exhibiting a range of neurophysiologically realistic spiking behaviours depending on the parameters given. We use the [izhikevich2007cell](https://docs.neuroml.org/Userdocs/Schemas/Cells.html#izhikevich2007cell) version here. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "izh0 = nml_doc.add(\n", + " \"Izhikevich2007Cell\",\n", + " id=\"izh2007RS0\", v0=\"-60mV\", C=\"100pF\", k=\"0.7nS_per_mV\", vr=\"-60mV\",\n", + " vt=\"-40mV\", vpeak=\"35mV\", a=\"0.03per_ms\", b=\"-2nS\", c=\"-50.0mV\", d=\"100pA\")\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a network and add it to the model\n", + "\n", + "We add a [network](https://docs.neuroml.org/Userdocs/Schemas/Networks.html#network) to the document created above. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "net = nml_doc.add(\"Network\", id=\"IzNet\", validate=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a population of defined cells and add it to the model\n", + "\n", + "A [population](https://docs.neuroml.org/Userdocs/Schemas/Networks.html#schema-population) of size 1 of these cells is created and then added to the network. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "size0 = 1\n", + "pop0 = net.add(\"Population\", id=\"IzhPop0\", component=izh0.id, size=size0)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define an external stimulus and add it to the model\n", + "\n", + "On its own the cell will not spike, so we add a small current to it in the form of a [pulse generator](https://docs.neuroml.org/Userdocs/Schemas/Inputs.html#pulsegenerator) which will apply a square pulse of current. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "pg = nml_doc.add(\n", + " \"PulseGenerator\",\n", + " id=\"pulseGen_%i\" % 0, delay=\"0ms\", duration=\"1000ms\",\n", + " amplitude=\"0.07 nA\"\n", + ")\n", + "exp_input = net.add(\"ExplicitInput\", target=\"%s[%i]\" % (pop0.id, 0), input=pg.id)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3) Write, print and validate the generated file \n", + "\n", + "### Write the NeuroML model to a file" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Written network file to: izhikevich2007_single_cell_network.nml\n" + ] + } + ], + "source": [ + "nml_file = 'izhikevich2007_single_cell_network.nml'\n", + "writers.NeuroMLWriter.write(nml_doc, nml_file)\n", + "print(\"Written network file to: \" + nml_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Print out the file\n", + "\n", + "Here we print the XML for the saved NeuroML file. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n" + ] + } + ], + "source": [ + "with open(nml_file) as f: \n", + " print(f.read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Validate the NeuroML model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "It's valid!\n" + ] + } + ], + "source": [ + "validate_neuroml2(nml_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4) Simulating the model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a simulation instance of the model\n", + "\n", + "The NeuroML file does not contain any information on how long to simulate the model for or what to save etc. For this we will need a [LEMS simulation file](https://docs.neuroml.org/Userdocs/LEMSSimulation.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading NeuroML2 file: /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/izhikevich2007_single_cell_network.nml\n" + ] + } + ], + "source": [ + "simulation_id = \"example-single-izhikevich2007cell-sim\"\n", + "simulation = LEMSSimulation(sim_id=simulation_id,\n", + " duration=1000, dt=0.1, simulation_seed=123)\n", + "simulation.assign_simulation_target(net.id)\n", + "simulation.include_neuroml2_file(nml_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the output file to store simulation outputs\n", + "\n", + "Here, we record the neuron's membrane potential to the specified data file." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "simulation.create_output_file(\n", + " \"output0\", \"%s.v.dat\" % simulation_id\n", + ")\n", + "simulation.add_column_to_output_file(\"output0\", 'IzhPop0[0]', 'IzhPop0[0]/v')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Save the simulation to a file" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + "\n", + "\n" + ] + } + ], + "source": [ + "lems_simulation_file = simulation.save_to_file()\n", + "with open(lems_simulation_file) as f: \n", + " print(f.read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the simulation using the jNeuroML simulator" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Loading LEMS file: LEMS_example-single-izhikevich2007cell-sim.xml and running with jNeuroML\n", + "pyNeuroML >>> INFO - Executing: (java -Xmx2G -Djava.awt.headless=true -jar \"/opt/homebrew/anaconda3/envs/py39n/lib/python3.9/site-packages/pyneuroml/lib/jNeuroML-0.13.0-jar-with-dependencies.jar\" LEMS_example-single-izhikevich2007cell-sim.xml -nogui -I '') in directory: .\n", + "pyNeuroML >>> INFO - Command completed successfully!\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pynml.run_lems_with_jneuroml(\n", + " lems_simulation_file, max_memory=\"2G\", nogui=True, plot=False\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot the recorded data" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pyNeuroML >>> INFO - Generating plot: Membrane potential\n", + "pyNeuroML >>> INFO - Saving image to /Users/padraig/git/Documentation/source/Userdocs/NML2_examples/SingleNeuron.png of plot: Membrane potential\n", + "pyNeuroML >>> INFO - Saved image to SingleNeuron.png of plot: Membrane potential\n" + ] + }, + { + "data": { + "image/png": "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dkChUEChUKBv375mSK39skQ+b9myBUOGDEHdunXh6uqKOnXq4NFHH8Wnn35qxpTbF3Pmc3Z2NubMmYP27dvD19cXLi4uqFu3Lp588kls3brVAqmXvujoaMyfPx8TJ05Ey5Yt4ezsDIVCgc8//7xK142MjMTAgQPh5+cHDw8PNGnSBB988AGysrLMlHIAApGR3njjDQGA4OzsLPTr108YPny4UL16dQGA0K1bNyEnJ6dS11u/fr3g7OwsABA6dOggjB49WggNDRUACP7+/kJMTIyFvom0mSufCwsLBQACAMHb21vo1auX8MwzzwjdunUTnJycBABCx44dhQcPHlj2C0mYue9pfampqUL9+vUFhUIhABD69OljxpTbF3Pnc35+vjBq1CgBgODh4SH07t1bGDNmjNCrVy+hTp06Qq1atSz0TaTNnPmcnJwsNGvWTFd/9OvXTxg9erQQERGhq1def/11C34badLmcek/n332mcnXnDt3rgBAUCgUwmOPPSaMGjVKqFu3rgBACA8PF+7fv2+WtDPgI6Ns3rxZV/BPnTql+/n9+/eFli1bCgCEt956y+jr3bp1S/D09BQACIsXL9b9vKioSBg3bpwuCFSr1Wb9HlJnznwuLCwU2rVrJ6xbt07Iy8sr8dq5c+eEevXqCQCE559/3qzfwV6Y+54u7dlnnxWcnJyEKVOmyDrgs0Q+jx8/XgAgDBs2zKAxVKlUwpEjR8ySdnti7nx+/fXXBQBCu3bthJSUlBKvbd++XddZl1teL126VHj77beF3377Tbh8+bLw3HPPVSngO336tKBQKAQnJydhx44dup9nZ2cLffr0EQAII0aMMEvaGfCRUTp06CAAED7//HOD1w4cOCAAENzc3IS0tDSjrvfOO+8IAIS+ffsavJaZmSlUq1ZNACD89ddfVU67PTF3Pj/Mr7/+qhshKSgoqPL17I0l83rTpk0CAOGdd94Rfv75Z1kHfObO58jISAGA0KJFC1net+Uxdz63aNFCACCsW7euzNcff/xxAYAwd+7cKqXb3k2YMKFKAZ92pPqll14yeC0+Pl5QKpUCAOHy5ctVTarANXxUoVu3buHEiRMAgLFjxxq83q1bNwQGBiI/Px87duww6pqbN28u93re3t4YMmQIAGDTpk2mJtvuWCKfH6Zt27YAgNzcXCQnJ1f5evbEknmdnJyMV155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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the data from the file and plot the graph for the membrane potential\n", + "# using the pynml generate_plot utility function.\n", + "data_array = np.loadtxt(\"%s.v.dat\" % simulation_id)\n", + "pynml.generate_plot(\n", + " [data_array[:, 0]], [data_array[:, 1]],\n", + " \"Membrane potential\", show_plot_already=True,\n", + " xaxis=\"time (s)\", yaxis=\"membrane potential (V)\",\n", + " save_figure_to=\"SingleNeuron.png\"\n", + " \n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/Userdocs/NeuroMLv1.md b/_sources/Userdocs/NeuroMLv1.md new file mode 100644 index 00000000..f8cf8947 --- /dev/null +++ b/_sources/Userdocs/NeuroMLv1.md @@ -0,0 +1,34 @@ +(userdocs:neuromlv1)= +# NeuroML v1 + +```{warning} +NeuroML v1.x is deprecated. This page is maintained for archival purposes only. + +Please use {ref}`NeuroML v2 `. + +{ref}`neuroConstruct ` can be used for converting NeuroML v1 models into NeuroML v2. +``` + +There are three Levels of compliance to the NeuroML v1 specifications: + +## Level 1 + +- [Metadata v1.8.1](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level1/Metadata_v1.8.1.xsd) +- [MorphML v1.8.1](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level1/MorphML_v1.8.1.xsd) + +Any Level 1 NeuroML v1 file will also be compliant to [this schema](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level1/NeuroML_Level1_v1.8.1.xsd). + +## Level 2 + +- [Biophysics v1.8.1](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level2/Biophysics_v1.8.1.xsd) +- [ChannelML v1.8.1](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level2/ChannelML_v1.8.1.xsd) + +Any Level 1 or Level 2 NeuroML v1 file will also be compliant to [this schema](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level2/NeuroML_Level2_v1.8.1.xsd). + +## Level 3 + +- [NetworkML v1.8.1](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level3/NetworkML_v1.8.1.xsd) + +Any Level 1 or Level 2 or Level 3 NeuroML v1 file will also be compliant to [this schema](https://github.com/NeuroML/org.neuroml1.model/blob/master/src/main/resources/NeuroML1Schemas/Level3/NeuroML_Level3_v1.8.1.xsd). + +These files are archived in [this GitHub repository](https://github.com/NeuroML/org.neuroml1.model/tree/master/src/main/resources/NeuroML1Schemas). diff --git a/_sources/Userdocs/NeuroMLv2.md b/_sources/Userdocs/NeuroMLv2.md new file mode 100644 index 00000000..c8bdfaef --- /dev/null +++ b/_sources/Userdocs/NeuroMLv2.md @@ -0,0 +1,37 @@ +(userdocs:neuromlv2)= +# NeuroML v2 + +The current stable version of NeuroML is v2.3, and the XSD Schema for this can be found [here](https://github.com/NeuroML/NeuroML2/blob/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +The following figure, taken from Cannon et al. 2014 ({cite}`Cannon2014`) shows some of the core elements defined in NeuroML version 2 (note: these key elements haven't changed since that publication). + +```{figure} ../images/Figure6a.png +:alt: Elements defined in the NeuroML schema, version 2. +:align: center + +Elements defined in the NeuroML schema, version 2. +``` + + + +You can see the complete definitions of NeuroML 2 entities in the following pages. +You can also search this documentation for specific entities that you may be using in your NeuroML models. + +Examples of files using the NeuroML 2 schema, and some of the elements they use are: + +| Example file | NeuroML elements used | +| --- | --- | +| [A simple cell with a morphology & segments arranged into groups](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_SimpleMorphology.nml) | {ref}` `, {ref}` `, {ref}` `, {ref}` ` | +| [A cell specifying biophysical properties (channel densities, passive electrical properties, etc.)](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_FullCell.nml) | {ref}` `, {ref}` `, {ref}` ` | +| [A simple HH Na+ channel](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_SimpleIonChannel.nml) | {ref}` `, {ref}` `, {ref}` ` | +| [Some of the simplified spiking neuron models which are supported](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_AbstractCells.nml) | {ref}` `, {ref}` `, {ref}` `, {ref}` ` | +| [Synapse models ](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_SynapseTypes.nml) | {ref}` `, {ref}` `, {ref}` `, {ref}` ` | +| [A network of cells positioned in 3D and synaptically connected ](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_InstanceBasedNetwork.nml) | {ref}` `, {ref}` `, {ref}` `, {ref}` `, {ref}` ` | + + +NeuroML files containing the XML representation of the model can be {ref}`validated ` to ensure all of the correct tags/attributes are present. + +**But** how do we know how the model is actually meant to use the specified attributes in an element? The schema only says that `leakReversal`, `thresh`, etc. are allowed attributes on `iafCell`, but how are these used to calculate the membrane potential? The answer lies in another, lower-level language, called LEMS (Low Entropy Model Specification). + +While valid NeuroML entities are contained in the schema, their underlying mathematical structure and composition rules must also be defined. +For this, NeuroML version 2 makes use of {ref}`LEMS `. + diff --git a/_sources/Userdocs/NeuroMLv2AndLEMS.md b/_sources/Userdocs/NeuroMLv2AndLEMS.md new file mode 100644 index 00000000..4732a7ed --- /dev/null +++ b/_sources/Userdocs/NeuroMLv2AndLEMS.md @@ -0,0 +1,154 @@ +(userdocs:nml2lems)= +# NeuroML 2 and LEMS + +LEMS is an XML based language originally developed by Robert Cannon for specifying generic models of hybrid dynamical systems. Models defined in LEMS can also be simulated directly through a native interpreter. + +- **ComponentType** elements define the behaviour of a specific type of model and specify **Parameters**, **StateVariables**, and their **Dynamics** and **Structure** can be defined as templates for model elements (e.g. HH ion channels, abstract cells, etc.). The notion of a **ComponentType** is thus similar to that of a **class** in object oriented programming. +- **Components** are instances of these types, with specific values of **Parameters** (e.g. HH squid axon Na+ channel, I&F cell with threshold -60mV, etc.). **Components** play the same role as **objects** in object oriented programming. + +```{figure} ../images/NeuroML2_LEMS_Overview_web.svg +:alt: Figure showing relationship between LEMS and NeuroML2 + +This image (from Blundell et al. 2018 ({cite}`Blundell2018`)) shows the usage of LEMS **ComponentTypes** and **Components** in NeuroML. +Elements in NeuroML v2 are **Components** which have a corresponding structural and mathematical definition in LEMS **ComponentTypes**. +``` + +On the left side of the figure, examples are shown of the (truncated) XML representations of: + +- (blue) a {ref}`network ` containing two {ref}`populations ` of {ref}`integrate-and-fire cells ` connected by a single {ref}`projection ` between them; +- (green) a {ref}`spiking neuron model ` as described by Izhikevich (2003); +- (yellow) a {ref}`conductance based synapse ` with a single exponential decay waveform. + +On the right, the definition of the structure and dynamics of these elements in the LEMS language is shown. +Each element has a corresponding **ComponentType** definition, describing the parameters (as well as their dimensions, not shown) and the dynamics in terms of state variables and their derivatives, any derived variables, and the behaviour when certain conditions are met or events are received (for example, the emission of a spike after a given threshold is crossed). + +(userdocs:neuromlv2inlems)= +## NeuroML 2 Component Type definitions in LEMS + +The standard set of **ComponentType** definitions for the core NeuroML2 elements are contained in a curated set of files (below) though users are {ref}`free to define their own ComponentTypes to extend the scope of the language `. + +- {ref}`Dimensions/units allowed ` ([source in LEMS](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/NeuroMLCoreDimensions.xml?view=markup)) +- {ref}`Cell models ` ([source in LEMS](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Cells.xml?view=markup)) +- {ref}`Network elements ` ([source in LEMS](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Networks.xml?view=markup)) +- {ref}`Ion channels ` ([source in LEMS](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Channels.xml?view=markup)) +- {ref}`Synapse models ` ([source in LEMS](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Synapses.xml?view=markup)) +- {ref}`Mapping of PyNN cells & synapses ` ([source in LEMS](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/PyNN.xml?view=markup)) + + + +Here, for example, the {ref}`izhikevich2007Cell ` is defined in the [NeuroML schema](https://github.com/NeuroML/NeuroML2/blob/master/Schemas/NeuroML2/NeuroML_v2.2.xsd) as having the following internal attributes: + +```{code-block} xml + + + + + + + + + + + + + + + +``` + +Correspondingly, its **ComponentType** dynamics are defined in the LEMS file, [Cells.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Cells.xml). +(Note: you do not need to read the XML LEMS definitions, you can see this information in a well formatted form {ref}`here in the documentation itself `) + +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +We can define **Component**s of the {ref}`izhikevich2007Cell ` **ComponentType** with the parameters we need. For example, the {ref}`izhikevich2007Cell ` neuron model can exhibit different spiking behaviours, so we can define a regular spiking **Component**, or another **Component** that exhibits bursting. + +```{code-block} xml + +``` + +Once these **Component**s are defined in the NeuroML document, we can use **Instance**s of them to create populations and networks, and so on. + +```{admonition} You don't have to write in XML... +A quick reminder that while XML files can be edited in a standard text editor, you generally don't have to create/update them by hand. {ref}`This guide ` goes through the steps of creating an example using the {ref}`izhikevich2007Cell ` model in Python using {ref}`libNeuroML ` and {ref}`pyNeuroML ` +``` + +Using LEMS to specify the core of NeuroML version 2 has the following significant advantages: + +- NeuroML 2 XML files can be used standalone by applications (exported/imported) in the same way as NeuroML v1.x, without reference to the LEMS definitions, easing the transition for v1.x compliant applications +- Any NeuroML 2 **ComponentType** can be extended and will be usable/translatable by any application (e.g. jLEMS) which understands LEMS + +The first point above means that a parsing application does not necessarily have to natively read the LEMS type definition for, e.g. an {ref}`izhikevich2007Cell ` element: it just has to map the NeuroML element parameters onto its own object model implementing that entity. +Ideally, the behaviour should be the same − which could be ascertained by testing against the reference LEMS interpreter implementation ([jLEMS](http://github.com/LEMS/jLEMS/)). + +The second point above means that if an application does support LEMS, it can automatically parse (and generate code for) a wide range of NeuroML 2 cells, channels and synapses, including any new **ComponentType** derived from these, without having to natively know anything about channels, cell models, etc. + +```{admonition} jnml and pynml handle both LEMS and NeuroML 2. +:class: tip +{ref}`jNeuroML ` and {ref}`pynml ` handle both LEMS and NeuroML 2. +They bundle jLEMS together with the LEMS definitions for NeuroML 2 ComponentTypes, and can simulate any LEMS model as well as many NeuroML 2 models. +``` +(userdocs:neuromlv2inlems:more)= +## More information + +While the {ref}`tutorials ` cover many of the key points of using LEMS with NeuroML, there are some points which require further explanation: + +- {ref}`What are the conventions/best practices to follow in naming NeuroML/LEMS files/elements? ` +- {ref}`How are units and dimensions handled in NeuroML and LEMS? ` +- {ref}`How do I use a LEMS Simulation file to specify how to execute a NeuroML model? ` +- {ref}`How can I extend NeuroML model to include new types using LEMS? ` +- {ref}`What is the correct format/usage of paths and quantities in NeuroML and LEMS? ` diff --git a/_sources/Userdocs/OptimisingNeuroMLModels.md b/_sources/Userdocs/OptimisingNeuroMLModels.md new file mode 100644 index 00000000..1919a0f9 --- /dev/null +++ b/_sources/Userdocs/OptimisingNeuroMLModels.md @@ -0,0 +1,422 @@ +(userdocs:optimising)= +# Optimising/fitting NeuroML Models + +{ref}`pyNeuroML ` includes the [NeuroMLTuner](https://pyneuroml.readthedocs.io/en/development/pyneuroml.tune.html#module-pyneuroml.tune.NeuroMLTuner) module for the tuning and optimisation of NeuroML models against provided data. +This uses the [Neurotune](https://github.com/NeuralEnsemble/neurotune/) Python package for the fitting of models using evolutionary computation. + +This page will walk through an example model optimisation. + +
+
+
+
+ +```{figure} ./NML2_examples/fitted_izhikevich_sim-exp-v.png +:alt: Membrane potential from example experimental data. + +Membrane potential from the experimental data. +``` +
+ +
+
+
+ +```{figure} ./NML2_examples/fitted_izhikevich_output.png +:alt: Membrane potential obtained from example fitted model. + +Membrane potential obtained from the model with highest fitness. +``` + +
+ +
+
+
+ +The Python script used to run the optimisation and generate the graphs is given below. +This can be adapted for other optimisations. +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +---- +``` +(userdocs:optimising:data)= +## Loading data and calculating metrics to use for optimisation + +The first step in the optimisation of the model is to obtain the data that the model is to be fitted against. +In this example, we will use the data set of CA1 pyramidal cell recordings using an intact whole hippocampus preparation, including recordings of rebound firing {cite}`ferguson_2015_17794`. +The data set is provided in the [Neurodata Without Borders](https://nwb.org) (NWB) format. +It can can be downloaded [here on the Open Source Brain repository](https://github.com/OpenSourceBrain/NWBShowcase/tree/master/FergusonEtAl2015), and can also be viewed on the [NWB Explorer](https://nwbexplorer.opensourcebrain.org) web application: + +```{figure} ./NML2_examples/fitted_izhikevich_screenshot_nwbexplorer.png +:alt: Screenshot showing two recordings from FergusonEtAl2015_PYR3.nwb in NWB Explorer. + +Screenshot showing two recordings from FergusonEtAl2015_PYR3.nwb in NWB Explorer. +``` + +For this example, we will use the [FergusonEtAl2015_PYR3.nwb](https://github.com/OpenSourceBrain/NWBShowcase/blob/master/FergusonEtAl2015/FergusonEtAl2015_PYR3.nwb) data file. +We use the [PyNWB](https://pynwb.readthedocs.io/en/stable/) package to read it, and then pass the loaded data to our `get_data_metrics` function to extract the metrics we want to use for model fitting. + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 417-420 +---- +``` + +Similar to {ref}`libNeuroML `, PyNWB provides a Python object model to interact with NWB files. +You can learn more on using PyNWB in its [documentation](https://pynwb.readthedocs.io/en/stable/). + +Here, the data file includes recordings from multiple (33 in total) current clamp experiments that are numbered from 1 through 33. +We iterate over each recording individually to extract the membrane potential values and store them in `data_v`. +For each, we also calculate the time stamps for the recordings from the provided sampling rate. +We pass this information to the `simple_network_analysis` function provided by the [PyElectro](https://github.com/NeuralEnsemble/pyelectro) Python package to calculate features (metrics) that we will use for fitting a neuron model. + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 33-71 +---- +``` + +The features calculated by PyElectro for each recording, which we store in `analysis_results`, can be seen below: +```{literalinclude} ./NML2_examples/fitted_izhikevich_pyelectro_analysis_results.txt +---- +language: console +---- +``` +We now have the following information: + +- `analysis_results`: the results of the analysis by PyElectro; we need these to set the target values for our fitting +- `currents`: the value of stimulation current for each sweep we've chosen; we need this for our models +- `memb_vals`: the time series of the membrane potentials and recordings times; we'll use this to plot the membrane potentials later to compare our fitted model against + +(userdocs:optimising:running)= +## Running the optimisation + +To run the optimisation, we want to choose which of the 33 time series we want to fit our model against. +Ideally, we would want to fit our model to all of them. +Here, however, for simplicity and to keep the computation time in check, we only pick two of the 33 sweeps. +(As an exercise, you can change the list to see how that affects your fitting.) + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 425-426 +---- +``` + +The Neurotune optimiser uses the evolutionary computation method provided by the [Inspyred](https://github.com/aarongarrett/inspyred/) package. +In short: + +- the evolutionary algorithm starts with a population of models, each with a random value for a set of parameters constrained by a max/min value we have supplied +- it then calculates a fitness value for each model by comparing the features generated by the model to the target features that we provide +- in each generation, it finds the fittest models (parents) +- it mutates these to generate the next generation of models (offspring) +- it replaces the least fit models with fittest of the new individuals + +The idea is that by calculating the fittest parents and offspring, it will find the candidate models that fit the provided target data best. +You can read more about evolutionary computation online (e.g. [Wikipedia](https://en.wikipedia.org/wiki/Evolutionary_algorithm)). +More information on model fitting in computational neuroscience can also be found in the literature. +For example, see this review {cite}`Rossant2011,Prinz2004`. + +Here, we follow the following steps: + +- we set up a template NeuroML model that will be passed to the optimiser +- we list the parameters we want to fit, and provide the extents of their state spaces +- we list the target features that the optimiser will use to calculate fitness, and set their weights +- finally, we use the `run_optimisation` function to run the optimisation + +The `tune_izh_model` function shown below is the main workhorse function that does our fitting: +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 74-254 +---- +``` + +Let us walk through the different sections of this function. + +(userdocs:optimising:running:template)= +### Writing a template model + +In this example, we want to fit the parameters of an {ref}`Izhikevich cell ` to our data such that simulating the cell then gives us membrane potentials similar to those observed in the experiment. +Following the {ref}`Izhikevich network example `, we set up a template network with one Izhikevich cell for each experimental recording that we want to fit. +For each of these cells, we provide a current stimulus matching the current used in the current clamp experiments that we obtained our recordings from: +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 89-143 +---- +``` +The resultant network template model for our two chosen recordings is shown below: + +```{literalinclude} ./NML2_examples/TuneIzhFergusonPyr3.net.nml +---- +language: xml +---- +``` +Please note that the initial parameters of the Izhikevich Cell do not matter here because the optimiser will modify these to run the candidate simulations. + +(userdocs:optimising:running:params)= +### Setting up the optimisation parameters + +The next step is to set the features/metrics that we want to fit: + +The `parameters` dictionary contains the specifications of the parameters that we wish to fit, along with their minimum and maximum permitted values. + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 155-167 +---- +``` +The format of the parameter specification is: `ComponentType:ComponentID/VariableName[:VariableID]/Units`. +So, for example, to fit the Capacitance of the Izhikevich cell, our parameter specification string is: `izhikevich2007Cell:Izh2007/C/pF`. + +All NeuroML {ref}`Cell ` and {ref}`Channel ` ComponentTypes can be fitted using the `NeuroMLTuner`. + +Next, we specify the target data that we want to fit against. + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 169-213 +---- +``` + +As we have set up a cell for each recording that we want to fit to, we must also set the target value for each cell. +We pick four features from a subset of features that PyElectro provided us with: + +- `mean_spike_frequency` +- `average_last_1percent` +- `average_maximum` +- `average_minimum` + +The last two can only be calculated for membrane potential data that includes spikes. +Since a few of the experimental recordings to not show any spikes, these two metrics will not be calculated for them. +So, we only add them for the corresponding cell only if they are present in the features for the chosen recording. + +The format for the `target_data` is similar to that of the `parameters`. +The keys of the `target_data` dictionary are the specifications for the metrics. +The format for these is: `path/to/variable:pyelectro metric`. +You can learn more about constructing paths in NeuroML {ref}`here `. +The value for the each key is the corresponding metric that was calculated for us by PyElectro (in `analysis_results`). +The for loop will set the `target_data` to this (printed by pyNeuroML when we run the script): + +```{code-block} python +target_data = { + 'Pop0[0]/v:mean_spike_frequency': 7.033585370142431, + 'Pop0[0]/v:average_last_1percent': -60.84635798136393, + 'Pop0[0]/v:average_maximum': 58.73414, + 'Pop0[0]/v:average_minimum': -43.800358, + 'Pop0[1]/v:mean_spike_frequency': 10.8837614279495, + 'Pop0[1]/v:average_last_1percent': -60.380863189697266, + 'Pop0[1]/v:average_maximum': 54.52382, + 'Pop0[1]/v:average_minimum': -39.78882 +} +``` + +Similarly, we also set up the weights for each target metric in the `weights` variable: +```{code-block} python +weights = { + 'Pop0[0]/v:mean_spike_frequency': 1, + 'Pop0[0]/v:average_last_1percent': 1, + 'Pop0[0]/v: average_maximum': 1, + 'Pop0[0]/v:average_minimum': 1, + 'Pop0[1]/v:mean_spike_frequency': 1, + 'Pop0[1]/v:average_last_1percent': 1, + 'Pop0[1]/v:average_maximum': 1, + 'Pop0[1]/v:average_minimum': 1 + } +``` +For simplicity, we set the weights for all as `1` here. + +(userdocs:optimising:running:call)= +### Calling the optimisation function + +The last step is to call our `run_optimisation` function with the various parameters that we have set up. +Here, for simplicity, we use the `jNeuroML` simulator. +For multi-compartmental models, however, we will need to use the `jNeuroML_NEURON` simulator (since `jNeuroML` only supports single compartment simulations). +A number of arguments to the function are specific to evolutionary computation, and their discussion is beyond the scope of this tutorial. +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 215-254 +---- +``` + +The `run_optimisation` function will print out the optimisation report, and also return it so that it can be stored in a variable for further use. +The terminal output is shown below: + +```{code-block} console + +Ran 500 evaluations (pop: 100) in 582.205449 seconds (9.703424 mins total; 1.164411s per eval) + +---------- Best candidate ------------------------------------------ +{ 'Pop0[0]/v:average_last_1percent': -59.276969863333285, + 'Pop0[0]/v:average_maximum': 47.35760225, + 'Pop0[0]/v:average_minimum': -53.95061271428572, + 'Pop0[0]/v:first_spike_time': 170.1, + 'Pop0[0]/v:interspike_time_covar': 0.1330373936860586, + 'Pop0[0]/v:max_interspike_time': 190.57499999999982, + 'Pop0[0]/v:max_peak_no': 8, + 'Pop0[0]/v:maximum': 47.427714, + 'Pop0[0]/v:mean_spike_frequency': 6.957040276293886, + 'Pop0[0]/v:min_interspike_time': 135.25000000000003, + 'Pop0[0]/v:min_peak_no': 7, + 'Pop0[0]/v:minimum': -68.13577, + 'Pop0[0]/v:peak_decay_exponent': 0.0003379360943630205, + 'Pop0[0]/v:peak_linear_gradient': -3.270149536895308e-05, + 'Pop0[0]/v:spike_broadening': 0.982357731987536, + 'Pop0[0]/v:spike_frequency_adaptation': -0.016935379943933133, + 'Pop0[0]/v:spike_width_adaptation': 0.011971808793771004, + 'Pop0[0]/v:trough_decay_exponent': -0.0008421760726029059, + 'Pop0[0]/v:trough_phase_adaptation': -0.014231837120099502, + 'Pop0[1]/v:average_last_1percent': -59.28251401166662, + 'Pop0[1]/v:average_maximum': 47.242452454545464, + 'Pop0[1]/v:average_minimum': -48.287914, + 'Pop0[1]/v:first_spike_time': 146.7, + 'Pop0[1]/v:interspike_time_covar': 0.01075626702836981, + 'Pop0[1]/v:max_interspike_time': 91.67499999999998, + 'Pop0[1]/v:max_peak_no': 11, + 'Pop0[1]/v:maximum': 47.423363, + 'Pop0[1]/v:mean_spike_frequency': 10.973033769511423, + 'Pop0[1]/v:min_interspike_time': 88.20000000000002, + 'Pop0[1]/v:min_peak_no': 10, + 'Pop0[1]/v:minimum': -62.58064000000001, + 'Pop0[1]/v:peak_decay_exponent': 0.0008036004162568405, + 'Pop0[1]/v:peak_linear_gradient': -0.00012436953066659044, + 'Pop0[1]/v:spike_broadening': 0.9877761288704633, + 'Pop0[1]/v:spike_frequency_adaptation': 0.0064956079899488595, + 'Pop0[1]/v:spike_width_adaptation': 0.008982392557695507, + 'Pop0[1]/v:trough_decay_exponent': -0.004658690933014975, + 'Pop0[1]/v:trough_phase_adaptation': 0.009514671770845617} + +TARGETS: +{ 'Pop0[0]/v:average_last_1percent': -60.84635798136393, + 'Pop0[0]/v:average_maximum': 58.73414, + 'Pop0[0]/v:average_minimum': -43.800358, + 'Pop0[0]/v:mean_spike_frequency': 7.033585370142431, + 'Pop0[1]/v:average_last_1percent': -60.380863189697266, + 'Pop0[1]/v:average_maximum': 54.52382, + 'Pop0[1]/v:average_minimum': -39.78882, + 'Pop0[1]/v:mean_spike_frequency': 10.8837614279495} + +TUNED VALUES: +{ 'Pop0[0]/v:average_last_1percent': -59.276969863333285, + 'Pop0[0]/v:average_maximum': 47.35760225, + 'Pop0[0]/v:average_minimum': -53.95061271428572, + 'Pop0[0]/v:mean_spike_frequency': 6.957040276293886, + 'Pop0[1]/v:average_last_1percent': -59.28251401166662, + 'Pop0[1]/v:average_maximum': 47.242452454545464, + 'Pop0[1]/v:average_minimum': -48.287914, + 'Pop0[1]/v:mean_spike_frequency': 10.973033769511423} + +FITNESS: 0.003633 + +FITTEST: { 'izhikevich2007Cell:Izh2007/C/pF': 240.6982897890555, + 'izhikevich2007Cell:Izh2007/a/per_ms': 0.03863507615280202, + 'izhikevich2007Cell:Izh2007/b/nS': 2.0112449831346746, + 'izhikevich2007Cell:Izh2007/c/mV': -43.069939785498356, + 'izhikevich2007Cell:Izh2007/d/pA': 212.50982499591083, + 'izhikevich2007Cell:Izh2007/k/nS_per_mV': 0.24113869560362797, + 'izhikevich2007Cell:Izh2007/vpeak/mV': 47.44063356996336, + 'izhikevich2007Cell:Izh2007/vr/mV': -59.283747806929135, + 'izhikevich2007Cell:Izh2007/vt/mV': -48.9131459978619} + +``` + +It will also generate a number of plots (shown below): + +- showing the evolution of the parameters being fitted, with indications of the fitness value: larger circles mean more fitness +- the change in the overall fitness value as the population evolves +- distributions of the values of the parameters being fitted, with indications of the fitness value: darker lines mean higher fitness + +```{figure} ./NML2_examples/fitted_izhikevich_scatter.png +:alt: Evolution of parameters. + +The figure shows the values of various parameters throughout the evolution, with larger circles having higher values of fitness. +``` +```{figure} ./NML2_examples/fitted_izhikevich_fitness.png +:alt: Evolution of fitness. + +The figure shows the trend of the fitness throughout the evolution. +``` +```{figure} ./NML2_examples/fitted_izhikevich_hist.png +:alt: Histograms of values of fitting parameters. + +The figure shows the distribution of values that for each parameter throughout the evolution. Darker lines have higher fitness values. + +``` + +(userdocs:optimising:results)= +## Viewing results + +The tuner also generates a plot with the membrane potential of a cell using the fitted parameter values (shown on the top of the page). +Here, to document how the fitted parameters are to be extracted from the output of the `run_optimisation` function, we also construct a model to use the fitted parameters ourselves and plot the membrane potential to compare it against the experimental data. + +(userdocs:optimising:results:run_model)= +### Extracting results and running a fitted model + +This is done in the `run_fitted_cell_simulation` function: + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 257-354 +---- +``` + +First, we extract the fitted parameters from the dictionary returned by the `run_optimisation` function. +Then, we use these parameters to set up a simple NeuroML network and run a test simulation, recording the values of membrane potentials generated by the cells. +Please note that the current stimulus to the cells in this test model must also match the values that were used in the experiment, and so also in the fitting. + +(userdocs:optimising:results:plotting)= +### Plotting model generated and experimentally recorded membrane potentials + +Finally, in the `plot_sim_data` function, we plot the membrane potentials from our fitted cells and the experimental data to see visually inspect the results of our fitting: + +```{literalinclude} ./NML2_examples/tune-izhikevich.py +---- +language: python +lines: 356-409 +---- +``` + +This generates the following figures: + +
+
+
+
+ +```{figure} ./NML2_examples/fitted_izhikevich_sim-exp-v.png +:alt: Membrane potential from example experimental data. + +Membrane potential from the experimental data. +``` +
+ +
+
+
+ +```{figure} ./NML2_examples/fitted_izhikevich_output.png +:alt: Membrane potential obtained from example fitted model. + +Membrane potential obtained from the model with highest fitness. +``` + +
+ +
+
+
+ + +We can clearly see the similarity between our fitted model and the experimental data. +A number of tweaks can be made to improve the fitting. +For example, pyNeuroML also provides a two staged optimisation function: [run_2stage_optimisation](https://pyneuroml.readthedocs.io/en/development/pyneuroml.tune.html#pyneuroml.tune.NeuroMLTuner.run_2stage_optimization) that allows users to optimise sets of parameters in two different stages. +The graphs also show ranges of parameters that provide fits, so users can also hand-tune their models further as required. diff --git a/_sources/Userdocs/Paths.md b/_sources/Userdocs/Paths.md new file mode 100644 index 00000000..ce89af5a --- /dev/null +++ b/_sources/Userdocs/Paths.md @@ -0,0 +1,193 @@ +(userdocs:paths)= +# Paths + +Since NeuroMLv2 and LEMS are both XML based, entities in models and simulations must be referred to using *paths* ([XPath](https://en.wikipedia.org/wiki/XPath) like). +This page documents how paths can be constructed, and how they can be used to refer to entities in NeuroML/LEMS based models and simulations (e.g. in a {ref}`LEMS Simulation file `). + +```{list-table} +:header-rows: 1 +:name: paths-operators + +* - operator + - description + - function + - example +* - {code}`/` + - forward slash + - used to split the levels in a path string + - see {ref}`below ` +* - {code}`.` + - single period + - refers to the level of the current node (usually omitted) + - see {ref}`below ` +* - {code}`..` + - two periods + - refers to the level of the current node's parent node + - see {ref}`below ` +* - {code}`[x]` + - square brackets + - used to refer to a particular instance (in this case, {code}`x`) in Components/Elements that have a `size` attribute (like {ref}`population `) + - see {ref}`below ` +* - {code}`:` + - colon + - used to refer to a particular Component instance for {code}`attachments` + - [ex](https://github.com/NeuroML/NeuroML2/blob/master/LEMSexamples/LEMS_NML2_Ex25_MultiComp.xml#L45) +``` +Paths start from any element and ascend/descend to refer to the entity that is to be referenced. + +(userdocs:paths:example)= +## Example + +For example, in the following block of code, based on the {ref}`Izhikevich network example `, a network is defined in NeuroML with 2 populations: +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + ... + + + + + + + + +``` +Here, in the `explicitInput` node, we need to refer to neurons of the `IzPop0` `population` node. +Since `explicitInput` and `population` are *siblings* (both have the `IzNet` `network` as *parent*), they are at the same *level*. +Therefore, in `explicitInput`, one can refer directly to `IzPop0`. + +The `projection` and `population` nodes are also *siblings* and therefore are at the same level. +So, in the `projection` tag also, we can refer to the `population` nodes directly. +The `connection` nodes, however, are *children* of the `projection` node. +Therefore, for the `connection` nodes, the `population` nodes are at the *parent* level, and we must use `../IzPop0` to refer to them. + +`../IzPop0` means "go up one level to the parent level (to `projection`) and then refer to `IzPop0`". +`../` can be used as many times as required and wherever required in the path. +For example, `../../../` would mean "go up three levels". + +(userdocs:pyneuroml)= +## Helper functions in pyNeuroML + +```{note} +These functions require {ref}`pyNeuroML ` version 0.5.18+, and {ref}`pylems ` version 0.5.8+. +``` + +From version 0.5.18, {ref}`pyNeuroML ` includes the [list_recording_paths_for_exposures](https://pyneuroml.readthedocs.io/en/development/pyneuroml.html#pyneuroml.pynml.list_recording_paths_for_exposures) helper function that can list the exposures and their recordable paths from a NeuroML 2 model: + +```{code-block} pycon +>>> import pyneuroml.pynml +>>> help(pynml.list_recording_paths_for_exposures) + +Help on function list_recording_paths_for_exposures in module pyneuroml.pynml: + +list_recording_paths_for_exposures(nml_doc_fn, substring='', target='') + List the recording path strings for exposures. + + This wraps around `lems.model.list_recording_paths` to list the recording + paths in the given NeuroML2 model. The only difference between the two is + that the `lems.model.list_recording_paths` function is not aware of the + NeuroML2 component types (since it's for any LEMS models in general), but + this one is. +``` + +It can be run on the example {ref}`Izhikevich network example `: +```{code-block} pycon +>>> pynml.list_recording_paths_for_exposures("izhikevich2007_network.nml", substring="", target="IzNet") +['IzNet/IzPop0[0]/iMemb', + 'IzNet/IzPop0[0]/iSyn', + 'IzNet/IzPop0[0]/u', + 'IzNet/IzPop0[0]/v', + 'IzNet/IzPop0[1]/iMemb', + 'IzNet/IzPop0[1]/iSyn', + 'IzNet/IzPop0[1]/u', + 'IzNet/IzPop0[1]/v', + 'IzNet/IzPop0[2]/iMemb', + 'IzNet/IzPop0[2]/iSyn', + 'IzNet/IzPop0[2]/u', + 'IzNet/IzPop0[2]/v', + 'IzNet/IzPop0[3]/iMemb', + 'IzNet/IzPop0[3]/iSyn', + 'IzNet/IzPop0[3]/u', + 'IzNet/IzPop0[3]/v', + 'IzNet/IzPop0[4]/iMemb', + 'IzNet/IzPop0[4]/iSyn', + 'IzNet/IzPop0[4]/u', + 'IzNet/IzPop0[4]/v', + 'IzNet/IzPop1[0]/iMemb', +.. +] +``` + + +Note that this function parsers the model description only, not the built simulation description. +Therefore, it will not necessarily list the complete list of paths. +Also worth noting is that since it parses and iterates over the expanded representation of the model, it can be slow and return long lists of results on larger models. +It is therefore, best to use this with the `substring` option to narrow its scope. + +An associated helper function [list_exposures](https://pyneuroml.readthedocs.io/en/development/pyneuroml.html?highlight=list_exposures#pyneuroml.pynml.list_exposures) is also available: +```{code-block} pycon +>>> import pyneuroml.pynml +>>> help(pynml.list_exposures) + +list_exposures(nml_doc_fn, substring='') + List exposures in a NeuroML model document file. + + This wraps around `lems.model.list_exposures` to list the exposures in a + NeuroML2 model. The only difference between the two is that the + `lems.model.list_exposures` function is not aware of the NeuroML2 component + types (since it's for any LEMS models in general), but this one is. + + The returned dictionary is of the form: + + .. + { + "component": ["exp1", "exp2"] + } +``` +When run on the example {ref}`Izhikevich network example `, it will return: + +```{code-block} pycon +>>> pynml.list_exposures("izhikevich2007_network.nml") + +{: {'g': , + 'i': }, + : {'u': , + 'iSyn': , + 'iMemb': , + 'v': }, + : {'i': }, + : {'i': }, + : {'i': }, + : {'i': }, + : {'i': }, +.. +} +``` + +This second function is primarily for use by the `list_recording_paths_for_exposures` function. + +As noted in the helper documentation, these are both based on a function of the same name implemented in {ref}`PyLEMS `, version 0.5.8+. diff --git a/_sources/Userdocs/Publications.md b/_sources/Userdocs/Publications.md new file mode 100644 index 00000000..acc87662 --- /dev/null +++ b/_sources/Userdocs/Publications.md @@ -0,0 +1,204 @@ +(citing)= +# Citing NeuroML and related publications + +This page documents how one can cite NeuroML in their work, and lists publications associated with the NeuroML initiative. + +## Citing NeuroML + +Please cite NeuroML in your work whenever you have used it. +Generally, you should cite the particular paper while discussing NeuroML in the text, and also note and cite the specific version of the NeuroML tool that has been used in the work. + +### Papers + +Please cite the following papers as required: + +(papers:neuroml2)= +#### NeuroML 2 and LEMS +```{admonition} The main citation for NeuroML 2 +:class: tip +Please cite the following paper when discussing NeuroML v2.0 or LEMS. +``` + +**Cannon RC, Gleeson P, Crook S, Ganapathy G, Marin B, Piasini E and Silver RA (2014)** +LEMS: A language for expressing complex biological models + in concise and hierarchical form and its use in underpinning NeuroML 2, +Frontiers in Neuroinformatics 8: 79. + +```{code-block} bibtex + +@Article{Cannon2014, + author = {Robert C. Cannon and Padraig Gleeson and Sharon Crook and Gautham Ganapathy and Boris Marin and Eugenio Piasini and R. Angus Silver}, + title = {{LEMS}: a language for expressing complex biological models in concise and hierarchical form and its use in underpinning {NeuroML} 2}, + doi = {10.3389/fninf.2014.00079}, + volume = {8}, + journal = {Frontiers in Neuroinformatics}, + publisher = {Frontiers Media {SA}}, + year = {2014}, +} +``` + +(papers:libneuroml)= +#### libNeuroML and PyLEMS +```{admonition} Citation for Python & NeuroML +:class: tip +Please cite the following paper when using the Python NeuroML libraries +``` +**Vella M, Cannon RC, Crook S, Davison AP, Ganapathy G, Robinson HP, Silver RA and Gleeson P (2014)** +libNeuroML and PyLEMS: using Python to combine procedural and declarative + modeling approaches in computational neuroscience. +Frontiers in Neuroinformatics 8: 38. + +```{code-block} bibtex +@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}, + pages = {38}, + volume = {8}, + journal = {Frontiers in neuroinformatics}, + year = {2014}, +} +``` + + +(papers:neuroml1)= +#### NeuroML v1 +```{admonition} Citation for NeuroML v1 +:class: tip +Please cite the following paper when discussing NeuroML version 1. (deprecated) +``` +**Gleeson, P., S. Crook, R. C. Cannon, M. L. Hines, G. O. Billings, et al. (2010)** +NeuroML: A Language for Describing Data Driven + Models of Neurons and Networks with a High Degree of Biological Detail. +PLoS Computational Biology 6(6): e1000815. + +```{code-block} bibtex +@Article{Gleeson2010, + author = {Padraig Gleeson and Sharon Crook and Robert C. Cannon and Michael L. Hines and Guy O. Billings and Matteo Farinella and Thomas M. Morse and Andrew P. Davison and Subhasis Ray and Upinder S. Bhalla and Simon R. Barnes and Yoana D. Dimitrova and R. Angus Silver}, + title = {{NeuroML}: A Language for Describing Data Driven Models of Neurons and Networks with a High Degree of Biological Detail}, + doi = {10.1371/journal.pcbi.1000815}, + editor = {Karl J. Friston}, + number = {6}, + pages = {e1000815}, + volume = {6}, + journal = {{PLoS} Computational Biology}, + publisher = {Public Library of Science ({PLoS})}, + year = {2010}, +} +``` + +(papers:osb)= +#### Open Source Brain + +This paper describes version 1 of the [Open Source Brain](https://www.opensourcebrain.org) platform. Please cite this paper if you have made use of OSB in your work: + +**Gleeson P, Cantarelli M, Marin B, Quintana A, Earnshaw M, et al. (2019)** +Open Source Brain: a collaborative resource for visualizing, analyzing, simulating and developing standardized models of neurons and circuits. Neuron 103 (3):395–411 + +```{code-block} bibtex +@Article{Gleeson2019, + author = {Padraig Gleeson and Matteo Cantarelli and Boris Marin and Adrian Quintana and Matt Earnshaw and Sadra Sadeh and Eugenio Piasini and Justas Birgiolas and Robert C. Cannon and N. Alex Cayco-Gajic and Sharon Crook and Andrew P. Davison and Salvador Dura-Bernal and Andr{\'{a}}s Ecker and Michael L. Hines and Giovanni Idili and Frederic Lanore and Stephen D. Larson and William W. Lytton and Amitava Majumdar and Robert A. McDougal and Subhashini Sivagnanam and Sergio Solinas and Rokas Stanislovas and Sacha J. van Albada and Werner van Geit and R. Angus Silver}, + title = {Open Source Brain: A Collaborative Resource for Visualizing, Analyzing, Simulating, and Developing Standardized Models of Neurons and Circuits}, + doi = {10.1016/j.neuron.2019.05.019}, + number = {3}, + pages = {395--411}, + volume = {103}, + journal = {Neuron}, + publisher = {Elsevier {BV}}, + year = {2019}, +} +``` +### Software + +It is important to cite software used in scientific work to: + +- aid reproducibility of work +- to ensure that the developers of tools receive credit for their work. + +You can learn more about Software Citation Principles as set out by the [F1000 Software Citation working group](https://www.force11.org/group/software-citation-working-group) in [this work](https://peerj.com/articles/cs-86/) {cite}`Smith2016`. + +You can obtain the version of {ref}`pyNeuroML ` and associated tools using the following command (with example output): + +```{code-block} console +$ pynml -version +pyNeuroML v0.5.20 (libNeuroML v0.3.1, jNeuroML v0.11.1) +``` + +Each NeuroML software tool has a unique DOI and reference associated with each release at the [Zenodo archival facility](https://zenodo.org/search?page=1&size=20&q=neuroml). +On each entry, you will be able to find the DOI and citation of the particular version you are using, and you will also be able to download the citation in different formats at the bottom of the right hand side bar. + +## Other publications + +This section lists other publications related to NeuroML. + +**Günay, C. et al. (2008)** Computational intelligence in electrophysiology: Trends and open problems. +In Smolinski, Milanova and Hassanien, eds. Applications of Computational Intelligence + in Biology. Springer, Berlin/Heidelberg. + +**Gleeson, P., V. Steuber, and R. A. Silver (2007)** +neuroConstruct: A Tool for Modeling Networks of Neurons in 3D Space. Neuron. 54(2):219-235. + +**Cannon R. C., M. O. Gewaltig, P. Gleeson, U. S. Bhalla, H. Cornelis, M. L. Hines, F. W. Howell, E. Muller, J. R. Stiles, S. Wils, E. De Schutter (2007)** + Interoperability of Neuroscience Modeling Software: Current Status and Future Directions. + Neuroinformatics Volume 5, 127-138. + + +**Crook, S., P. Gleeson, F. Howell, J. Svitak and R.A. Silver (2007)** +MorphML: Level 1 of the NeuroML + standards for neuronal morphology data and model specification. Neuroinformatics. 5(2):96-104. + + +**Crook, S. and F. Howell (2007)** +XML for data representation and model +specification in neuroscience. In Methods in Molecular Biology Book Series: Neuroinformatics. ed. C. Crasto, +Humana Press.

+ +**Crook, S., D. Beeman, P. Gleeson and F. Howell (2005)** XML for model specification in neuroscience: An introduction and workshop summary. Brains, Minds, and Media. 1:bmm228 (urn:nbn:de:0009-3-2282).

+ +**Qi, W. and S. Crook (2004)** + +Tools for neuroinformatic data exchange: An XML +application for neuronal morphology data. Neurocomputing. +58-60C:1091-1095.

+ +**Goddard, N., M. Hucka, F. Howell, H. Cornelis, K. Shankar and D. Beeman (2001)** + Towards NeuroML: Model +description methods for collaborative modeling +in neuroscience. Philosophical Transactions of the Royal Society B. 356:1209-1228.

+ +### Book Chapters +**Crook, SM, HE Plesser, AP Davison (2013)** +Lessons from the past: approaches for reproducibility in computational neuroscience. +In JM Bower, ed. 20 Years of Computational Neuroscience, Springer + +**Gleeson, P, V Steuber, RA Silver and S Crook (2012)** +NeuroML. In Le Novere, ed. Computational Systems Biology, Springer. + + + +### Abstracts +**Cannon, R, P Gleeson, S Crook, RA Silver (2012)** A declarative model specification system allowing NeuroML to be extended with user-defined component types. BMC Neuroscience. 13(Suppl 1): P42. +

+ +**Gleeson P, S Crook, A Silver, R Cannon (2011)** + Development of NeuroML version 2.0: Greater extensibility, support for abstract neuronal models and interaction with Systems Biology languages. BMC Neuroscience. 12:P29. + +**Gleeson, P., S. Crook, S. Barnes and R.A. Silver (2008)** + +Interoperable model components for biologically +realistic single neuron and network models implemented in NeuroML. +Frontiers in Neuroinformatics. Conference Abstract: Neuroinformatics 2008. doi: 10.3389/conf.neuro.11.2008.01.135. + +**Larson, S. and M. Martone (2008)** + +A spatial framework for multi-scale +computational neuroanatomy. Frontiers in Neuroinformatics. Conference Abstract: Neuroinformatics 2008. doi: 10.3389/conf.neuro.11.2008.01.134. + +**Crook, S., P. Gleeson and R.A. Silver (2007)** +NetworkML: Level 3 of the NeuroML standards for multiscale model specification and +exchange. Society for Neuroscience Abstracts. 102.28. + +**Gleeson, P., S. Crook, V. Steuber and R.A. Silver (2007)** + + Using NeuroML and neuroConstruct to build neuronal network models for multiple + simulators. BMC Neuroscience. 8(2):P101. diff --git a/_sources/Userdocs/QuantitiesAndRecording.md b/_sources/Userdocs/QuantitiesAndRecording.md new file mode 100644 index 00000000..0e53a1e6 --- /dev/null +++ b/_sources/Userdocs/QuantitiesAndRecording.md @@ -0,0 +1,20 @@ +(userdocs:quantitiesandrecording)= +# Quantities and recording + +In LEMS and NeuroML, `quantities` from all `exposures` and all `events` can be recorded by referring to them using {ref}`paths `. +For examples, please see the {ref}`Getting Started with NeuroML ` section. + +(userdocs:quantitiesandrecording:events)= +## Recording events + +In NeuroML, all `event`s can be recorded to files declared using the {ref}`EventOutputFile ` component. +Once an `EventOutputFile` has been declared, events to record can be selected using the {ref}`EventSelection ` component. + +{ref}`pyNeuroML ` provides the [create_event_output_file](https://pyneuroml.readthedocs.io/en/development/pyneuroml.lems.html?highlight=add_selection_to_event_output_file#pyneuroml.lems.LEMSSimulation.LEMSSimulation.create_event_output_file) function to create a `EventOutputFile` to record `events` to, and the [add_selection_to_event_output_file](https://pyneuroml.readthedocs.io/en/development/pyneuroml.lems.html?highlight=add_selection_to_event_output_file#pyneuroml.lems.LEMSSimulation.LEMSSimulation.add_selection_to_event_output_file) function to record `events` to the declared data file(s). + +(userdocs:quantitiesandrecording:exposures)= +## Recording quantities from exposures +In NeuroML, all `quantities` can be recorded to files declared using the {ref}`OutputFile ` component. +Once the `OutputFile` has been declared, `quantities` to record can be selected using the {ref}`OutputColumn ` component. + +{ref}`pyNeuroML ` provides the [create_output_file](https://pyneuroml.readthedocs.io/en/development/pyneuroml.lems.html?highlight=add_selection_to_event_output_file#pyneuroml.lems.LEMSSimulation.LEMSSimulation.create_event_output_file) function to create a `OutputFile` to record `quantities` to, and the [add_column_to_output_file](https://pyneuroml.readthedocs.io/en/development/pyneuroml.lems.html?highlight=add_selection_to_event_output_file#pyneuroml.lems.LEMSSimulation.LEMSSimulation.create_event_output_file) function to select `quantities` to record to the declared data file(s). diff --git a/_sources/Userdocs/Schemas/Cells.md b/_sources/Userdocs/Schemas/Cells.md new file mode 100644 index 00000000..5337db96 --- /dev/null +++ b/_sources/Userdocs/Schemas/Cells.md @@ -0,0 +1,7222 @@ + +(schema:cells_)= +# Cells + +**Defines both abstract cell models ( e.g. {ref}`schema:izhikevichcell`, adaptive exponential integrate and fire cell, {ref}`schema:adexiafcell` ), point conductance based cell models ( {ref}`schema:pointcellcondbased`, {ref}`schema:pointcellcondbasedca` ) and cells models ( {ref}`schema:cell` ) which specify the {ref}`schema:morphology` ( containing {ref}`schema:segment`s ) and {ref}`schema:biophysicalproperties` separately.** + +--- + + +Original ComponentType definitions: [Cells.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//Cells.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:basecell)= + +## *baseCell* + + + + +extends *{ref}`schema:basestandalone`* + + + +Base type of any cell ( e.g. point neuron like {ref}`schema:izhikevich2007cell`, or a morphologically detailed {ref}`schema:cell` with {ref}`schema:segment`s ) which can be used in a {ref}`schema:population`. + + +`````{tab-set} +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseCell + +variable = BaseCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:basespikingcell)= + +## *baseSpikingCell* + + + + +extends *{ref}`schema:basecell`* + + + +Base type of any cell which can emit **spike** events. + + +`````{tab-set} +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event$Direction: out + +``` +```` +````` + +(schema:basecellmembpot)= + +## *baseCellMembPot* + + + + +extends *{ref}`schema:basespikingcell`* + + + +Any spiking cell which has a membrane potential **v** with units of voltage ( as opposed to a dimensionless membrane potential used in {ref}`schema:basecellmembpotdl` ). + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ Membrane potential ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` +````` + +(schema:basecellmembpotdl)= + +## *baseCellMembPotDL* + + + + +extends *{ref}`schema:basespikingcell`* + + + +Any spiking cell which has a dimensioness membrane potential, **V** ( as opposed to a membrane potential units of voltage, {ref}`schema:basecellmembpot` ). + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**V**$ Membrane potential $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` +````` + +(schema:basechannelpopulation)= + +## *baseChannelPopulation* + + + + +extends *{ref}`schema:basevoltagedeppointcurrent`* + + + +Base type for any current produced by a population of channels, all of which are of type **ionChannel**. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**ionChannel**$ $ {ref}`schema:baseionchannel` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:channelpopulation)= + +## channelPopulation + + + + +extends *{ref}`schema:basechannelpopulation`* + + + +Population of a **number** of ohmic ion channels. These each produce a conductance **channelg** across a reversal potential **erev,** giving a total current **i.** Note that active membrane currents are more frequently specified as a density over an area of the {ref}`schema:cell` using {ref}`schema:channeldensity`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ The reversal potential of the current produced ${ref}`schema:dimensions:voltage` +**number**$ The number of channels present. This will be multiplied by the time varying conductance of the individual ion channel (which extends _baseIonChannel_) to produce the total conductance $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**vShift** = 0mV$ $ {ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **channelg** = ionChannel->g + : **geff** = channelg * number + : **i** = geff * (erev - v) (exposed as **i**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelPopulation + +variable = ChannelPopulation( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + number: 'a NonNegativeInteger (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:channelpopulationnernst)= + +## channelPopulationNernst + + + + +extends *{ref}`schema:basechannelpopulation`* + + + +Population of a **number** of channels with a time varying reversal potential **erev** determined by Nernst equation. Note: hard coded for Ca only! + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**number**$ The number of channels present. This will be multiplied by the time varying conductance of the individual ion channel (which extends _baseIonChannel_) to produce the total conductance $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**R** = 8.3144621 J_per_K_per_mol$ $ {ref}`schema:dimensions:idealGasConstantDims` +**zCa** = 2$ $ Dimensionless +**F** = 96485.3 C_per_mol$ $ {ref}`schema:dimensions:charge_per_mole` +**vShift** = 0mV$ $ {ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ The reversal potential of the current produced, calculated from _caConcExt and _caConc ${ref}`schema:dimensions:voltage` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ The internal Ca2+ concentration, as calculated/exposed by the parent Component ${ref}`schema:dimensions:concentration` +**caConcExt**$ The external Ca2+ concentration, as calculated/exposed by the parent Component ${ref}`schema:dimensions:concentration` +**temperature**$ The temperature to use in the calculation of _erev. Note this is generally exposed by a _networkWithTemperature_. ${ref}`schema:dimensions:temperature` +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **singleChannelConductance** = ionChannel->g + : **totalConductance** = singleChannelConductance * number + : **erev** = (R * temperature / (zCa * F)) * log(caConcExt / caConc) (exposed as **erev**) + : **i** = totalConductance * (erev - v) (exposed as **i**) + + + + + + +```` +````` + +(schema:basechanneldensity)= + +## *baseChannelDensity* + + + + +Base type for a current of density **iDensity** distributed on an area of a {ref}`schema:cell`, flowing through the specified **ionChannel.** Instances of this ( normally {ref}`schema:channeldensity` ) are specified in the {ref}`schema:membraneproperties` of the {ref}`schema:cell`. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**ionChannel**$ $ {ref}`schema:baseionchannel` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iDensity**$ ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basechanneldensitycond)= + +## *baseChannelDensityCond* + + + + +extends *{ref}`schema:basechanneldensity`* + + + +Base type for distributed conductances on an area of a cell producing a ( not necessarily ohmic ) current. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**condDensity**$ ${ref}`schema:dimensions:conductanceDensity` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**gDensity**$ ${ref}`schema:dimensions:conductanceDensity` +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:variableparameter)= + +## variableParameter + + + + +Specifies a **parameter** ( e.g. condDensity ) which can vary its value across a **segmentGroup.** The value is calculated from **value** attribute of the {ref}`schema:inhomogeneousvalue` subelement. This element is normally a child of {ref}`schema:channeldensitynonuniform`, {ref}`schema:channeldensitynonuniformnernst` or {ref}`schema:channeldensitynonuniformghk` and is used to calculate the value of the conductance, etc. which will vary on different parts of the cell. The **segmentGroup** specified here needs to define an {ref}`schema:inhomogeneousparameter` ( referenced from **inhomogeneousParameter** in the {ref}`schema:inhomogeneousvalue` ), which calculates a **variable** ( e.g. p ) varying across the cell ( e.g. based on the path length from soma ), which is then used in the **value** attribute of the {ref}`schema:inhomogeneousvalue` ( so for example condDensity = f( p ) ). + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**parameter**$ +**segmentGroup**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**inhomogeneousValue**$ $ {ref}`schema:inhomogeneousvalue` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import VariableParameter + +variable = VariableParameter( + parameter: 'a string (required)' = None, + segment_groups: 'a string (required)' = None, + inhomogeneous_value: 'a InhomogeneousValue (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```` +````` + +(schema:inhomogeneousvalue)= + +## inhomogeneousValue + + + + +Specifies the **value** of an **inhomogeneousParameter.** For usage see {ref}`schema:variableparameter`. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**inhomogeneousParameter**$ +**value**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import InhomogeneousValue + +variable = InhomogeneousValue( + inhomogeneous_parameters: 'a string (required)' = None, + value: 'a string (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:channeldensitynonuniform)= + +## channelDensityNonUniform + + + + +extends *{ref}`schema:basechanneldensity`* + + + +Specifies a time varying ohmic conductance density, which is distributed on a region of the **cell.** The conductance density of the channel is not uniform, but is set using the {ref}`schema:variableparameter`. Note, there is no dynamical description of this in LEMS yet, as this type only makes sense for multicompartmental cells. A ComponentType for this needs to be present to enable export of NeuroML 2 multicompartmental cells via LEMS/jNeuroML to NEURON. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ The reversal potential of the current produced ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**ZERO_CURR_DENS** = 0 A_per_m2$ $ {ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**variableParameter**$ $ {ref}`schema:variableparameter` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **iDensity** = ZERO_CURR_DENS (exposed as **iDensity**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityNonUniform + +variable = ChannelDensityNonUniform( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + +``` +```` +````` + +(schema:channeldensitynonuniformnernst)= + +## channelDensityNonUniformNernst + + + + +extends *{ref}`schema:basechanneldensity`* + + + +Specifies a time varying conductance density, which is distributed on a region of the **cell,** and whose reversal potential is calculated from the Nernst equation. Hard coded for Ca only!. The conductance density of the channel is not uniform, but is set using the {ref}`schema:variableparameter`. Note, there is no dynamical description of this in LEMS yet, as this type only makes sense for multicompartmental cells. A ComponentType for this needs to be present to enable export of NeuroML 2 multicompartmental cells via LEMS/jNeuroML to NEURON. + + +`````{tab-set} +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**ZERO_CURR_DENS** = 0 A_per_m2$ $ {ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**variableParameter**$ $ {ref}`schema:variableparameter` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **iDensity** = ZERO_CURR_DENS (exposed as **iDensity**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityNonUniformNernst + +variable = ChannelDensityNonUniformNernst( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, +) +``` +```` +````` + +(schema:channeldensitynonuniformghk)= + +## channelDensityNonUniformGHK + + + + +extends *{ref}`schema:basechanneldensity`* + + + +Specifies a time varying conductance density, which is distributed on a region of the **cell,** and whose current is calculated from the Goldman-Hodgkin-Katz equation. Hard coded for Ca only!. The conductance density of the channel is not uniform, but is set using the {ref}`schema:variableparameter`. Note, there is no dynamical description of this in LEMS yet, as this type only makes sense for multicompartmental cells. A ComponentType for this needs to be present to enable export of NeuroML 2 multicompartmental cells via LEMS/jNeuroML to NEURON. + + +`````{tab-set} +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**ZERO_CURR_DENS** = 0 A_per_m2$ $ {ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**variableParameter**$ $ {ref}`schema:variableparameter` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **iDensity** = ZERO_CURR_DENS (exposed as **iDensity**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityNonUniformGHK + +variable = ChannelDensityNonUniformGHK( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, +) +``` +```` +````` + +(schema:channeldensity)= + +## channelDensity + + + + +extends *{ref}`schema:basechanneldensitycond`* + + + +Specifies a time varying ohmic conductance density, **gDensity,** which is distributed on an area of the **cell** ( specified in {ref}`schema:membraneproperties` ) with fixed reversal potential **erev** producing a current density **iDensity**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**condDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**erev**$ The reversal potential of the current produced ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**vShift** = 0mV$ $ {ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ Which _segmentGroup_ the channelDensity is placed on. If this is missing, it implies it is placed on all _segment_s of the _cell_ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**gDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **channelf** = ionChannel->fopen + : **gDensity** = condDensity * channelf (exposed as **gDensity**) + : **iDensity** = gDensity * (erev - v) (exposed as **iDensity**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensity + +variable = ChannelDensity( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:channeldensityvshift)= + +## channelDensityVShift + + + + +extends {ref}`schema:channeldensity` + + + +Same as {ref}`schema:channeldensity`, but with a **vShift** parameter to change voltage activation of gates. The exact usage of **vShift** in expressions for rates is determined by the individual gates. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**condDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**erev**$ The reversal potential of the current produced *(from {ref}`schema:channeldensity`)* ${ref}`schema:dimensions:voltage` +**vShift**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ Which _segmentGroup_ the channelDensity is placed on. If this is missing, it implies it is placed on all _segment_s of the _cell_ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**gDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityVShift + +variable = ChannelDensityVShift( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, + v_shift: 'a Nml2Quantity_voltage (required)' = None, +) +``` +```` +````` + +(schema:channeldensitynernst)= + +## channelDensityNernst + + + + +extends *{ref}`schema:basechanneldensitycond`* + + + +Specifies a time varying conductance density, **gDensity,** which is distributed on an area of the **cell,** producing a current density **iDensity** and whose reversal potential is calculated from the Nernst equation. Hard coded for Ca only! See https://github.com/OpenSourceBrain/ghk-nernst. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**condDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**R** = 8.3144621 J_per_K_per_mol$ $ {ref}`schema:dimensions:idealGasConstantDims` +**zCa** = 2$ $ Dimensionless +**F** = 96485.3 C_per_mol$ $ {ref}`schema:dimensions:charge_per_mole` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ Which _segmentGroup_ the channelDensityNernst is placed on. If this is missing, it implies it is placed on all _segment_s of the _cell_ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ The reversal potential of the current produced, calculated from caConcExt and caConc ${ref}`schema:dimensions:voltage` +**gDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ ${ref}`schema:dimensions:concentration` +**temperature**$ ${ref}`schema:dimensions:temperature` +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **channelf** = ionChannel->fopen + + + + +**Conditional Derived Variables** + +: IF caConcExt > 0 THEN +:   **gDensity** = condDensity \* channelf  (exposed as **gDensity**) +: IF caConcExt <= 0 THEN +:   **gDensity** = 0  (exposed as **gDensity**) +: IF caConcExt > 0 THEN +:   **erev** = (R \* temperature / (zCa \* F)) \* log(caConcExt / caConc)  (exposed as **erev**) +: IF caConcExt <= 0 THEN +:   **erev** = 0  (exposed as **erev**) +: IF caConcExt > 0 THEN +:   **iDensity** = gDensity \* (erev - v)  (exposed as **iDensity**) +: IF caConcExt <= 0 THEN +:   **iDensity** = 0  (exposed as **iDensity**) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityNernst + +variable = ChannelDensityNernst( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:channeldensitynernstca2)= + +## channelDensityNernstCa2 + + + + +extends *{ref}`schema:basechanneldensitycond`* + + + +This component is similar to the original component type {ref}`schema:channeldensitynernst` but it is changed in order to have a reversal potential that depends on a second independent Ca++ pool ( ca2 ). See https://github.com/OpenSourceBrain/ghk-nernst. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**condDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**R** = 8.3144621 J_per_K_per_mol$ $ {ref}`schema:dimensions:idealGasConstantDims` +**zCa** = 2$ $ Dimensionless +**F** = 96485.3 C_per_mol$ $ {ref}`schema:dimensions:charge_per_mole` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ Which _segmentGroup_ the channelDensityNernstCa2 is placed on. If this is missing, it implies it is placed on all _segment_s of the _cell_ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ The reversal potential of the current produced ${ref}`schema:dimensions:voltage` +**gDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc2**$ ${ref}`schema:dimensions:concentration` +**caConcExt2**$ ${ref}`schema:dimensions:concentration` +**temperature**$ ${ref}`schema:dimensions:temperature` +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **channelf** = ionChannel->fopen + + + + +**Conditional Derived Variables** + +: IF caConcExt2 > 0 THEN +:   **gDensity** = condDensity \* channelf  (exposed as **gDensity**) +: IF caConcExt2 <= 0 THEN +:   **gDensity** = 0  (exposed as **gDensity**) +: IF caConcExt2 > 0 THEN +:   **erev** = (R \* temperature / (zCa \* F)) \* log(caConcExt2 / caConc2)  (exposed as **erev**) +: IF caConcExt2 <= 0 THEN +:   **erev** = 0  (exposed as **erev**) +: IF caConcExt2 > 0 THEN +:   **iDensity** = gDensity \* (erev - v)  (exposed as **iDensity**) +: IF caConcExt2 <= 0 THEN +:   **iDensity** = 0  (exposed as **iDensity**) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityNernstCa2 + +variable = ChannelDensityNernstCa2( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, + variable_parameters: 'list of VariableParameter(s) (optional)' = None, +) +``` +```` +````` + +(schema:channeldensityghk)= + +## channelDensityGHK + + + + +extends *{ref}`schema:basechanneldensity`* + + + +Specifies a time varying conductance density, **gDensity,** which is distributed on an area of the cell, producing a current density **iDensity** and whose reversal potential is calculated from the Goldman Hodgkin Katz equation. Hard coded for Ca only! See https://github.com/OpenSourceBrain/ghk-nernst. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**permeability**$ ${ref}`schema:dimensions:permeability` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**R** = 8.3144621 J_per_K_per_mol$ $ {ref}`schema:dimensions:idealGasConstantDims` +**zCa** = 2$ $ Dimensionless +**F** = 96485.3 C_per_mol$ $ {ref}`schema:dimensions:charge_per_mole` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ Which _segmentGroup_ the channelDensityGHK is placed on. If this is missing, it implies it is placed on all _segment_s of the _cell_ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ ${ref}`schema:dimensions:concentration` +**temperature**$ ${ref}`schema:dimensions:temperature` +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **K** = (zCa * F) / (R * temperature) + : **expKv** = exp(-1 * K * v) + : **channelf** = ionChannel->fopen + + + + +**Conditional Derived Variables** + +: IF caConcExt > 0 THEN +:   **iDensity** = -1 \* channelf \* permeability \* zCa \* F \* K \* v \* ( caConc - (caConcExt \* expKv) ) / (1 - expKv)  (exposed as **iDensity**) +: IF caConcExt <= 0 THEN +:   **iDensity** = 0  (exposed as **iDensity**) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityGHK + +variable = ChannelDensityGHK( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + permeability: 'a Nml2Quantity_permeability (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, +) +``` +```` +````` + +(schema:channeldensityghk2)= + +## channelDensityGHK2 + + + + +extends *{ref}`schema:basechanneldensitycond`* + + + +Time varying conductance density, **gDensity,** which is distributed on an area of the cell, producing a current density **iDensity.** Modified version of Jaffe et al. 1994 ( used also in Lawrence et al. 2006 ). See https://github.com/OpenSourceBrain/ghk-nernst. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**condDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**VOLT_SCALE** = 1 mV$ $ {ref}`schema:dimensions:voltage` +**CONC_SCALE** = 1 mM$ $ {ref}`schema:dimensions:concentration` +**TEMP_SCALE** = 1 K$ $ {ref}`schema:dimensions:temperature` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ Which _segmentGroup_ the channelDensityGHK2 is placed on. If this is missing, it implies it is placed on all _segment_s of the _cell_ +**ion**$ Which ion flows through the channel. Note: ideally this needs to be a property of ionChannel only, but it's here as it makes it easier to select channelPopulations transmitting specific ions. + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**gDensity**$ *(from {ref}`schema:basechanneldensitycond`)* ${ref}`schema:dimensions:conductanceDensity` +**iDensity**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:currentDensity` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ ${ref}`schema:dimensions:concentration` +**temperature**$ ${ref}`schema:dimensions:temperature` +**v**$ *(from {ref}`schema:basechanneldensity`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **ionChannel** + + + + + + + + + +**Derived Variables** + : **V** = v / VOLT_SCALE + : **ca_conc_i** = caConc / CONC_SCALE + : **ca_conc_ext** = caConcExt / CONC_SCALE + : **T** = temperature / TEMP_SCALE + : **channelf** = ionChannel->fopen + : **gDensity** = condDensity * channelf (exposed as **gDensity**) + : **tmp** = (25 * T) / (293.15 * 2) + + + + +**Conditional Derived Variables** + +: IF V/tmp = 0. THEN +:   **pOpen** = tmp \* 1e-3 \* (1 - ((ca_conc_i/ca_conc_ext) \* exp(V/tmp))) \* (1 - (V/tmp)/2) +: IF V/tmp != 0. THEN +:   **pOpen** = tmp \* 1e-3 \* (1 - ((ca_conc_i/ca_conc_ext) \* exp(V/tmp))) \* ((V/tmp) / (exp(V/tmp) - 1)) +: IF ca_conc_ext > 0 THEN +:   **iDensity** = gDensity \* pOpen  (exposed as **iDensity**) +: IF ca_conc_ext <= 0 THEN +:   **iDensity** = 0  (exposed as **iDensity**) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ChannelDensityGHK2 + +variable = ChannelDensityGHK2( + id: 'a NmlId (required)' = None, + ion_channel: 'a NmlId (required)' = None, + cond_density: 'a Nml2Quantity_conductanceDensity (optional)' = None, + segment_groups: 'a NmlId (optional)' = 'all', + segments: 'a NonNegativeInteger (optional)' = None, + ion: 'a NmlId (required)' = None, +) +``` +```` +````` + +(schema:pointcellcondbased)= + +## pointCellCondBased + + + + +extends *{ref}`schema:basecellmembpotcap`* + + + +Simple model of a conductance based cell, with no separate {ref}`schema:morphology` element, just an absolute capacitance **C,** and a set of channel **populations.** Note: use of {ref}`schema:cell` is generally preferable ( and more widely supported ), even for a single compartment cell. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**thresh**$ The voltage threshold above which the cell is considered to be _spiking ${ref}`schema:dimensions:voltage` +**v0**$ The initial membrane potential of the cell ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**populations**$ $ {ref}`schema:basechannelpopulation` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **spiking**: Dimensionless + + + + + + + + + +**On Start** +: **v** = v0 +: **spiking** = 0 + + + +**On Conditions** + +: IF v > thresh AND spiking < 0.5 THEN +:    **spiking** = 1 +:    EVENT OUT on port: **spike** + +: IF v < thresh THEN +:    **spiking** = 0 + + + + + +**Derived Variables** + : **iChannels** = populations[*]->i(reduce method: add) + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iMemb** = iChannels + iSyn (exposed as **iMemb**) + + + + + + +**Time Derivatives** + : d **v** /dt = iMemb / C + + +```` +````` + +(schema:pointcellcondbasedca)= + +## pointCellCondBasedCa + + + + +extends *{ref}`schema:basecellmembpotcap`* + + + +TEMPORARY: Point cell with conductances and Ca concentration info. Not yet fully tested!!! TODO: Remove in favour of {ref}`schema:cell`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**thresh**$ The voltage threshold above which the cell is considered to be _spiking ${ref}`schema:dimensions:voltage` +**v0**$ The initial membrane potential of the cell ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**populations**$ $ {ref}`schema:basechannelpopulation` +**concentrationModels**$ $ {ref}`schema:concentrationmodel` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**iCa**$ ${ref}`schema:dimensions:current` +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **spiking**: Dimensionless + + + + + + + + + +**On Start** +: **v** = v0 +: **spiking** = 0 + + + +**On Conditions** + +: IF v > thresh AND spiking < 0.5 THEN +:    **spiking** = 1 +:    EVENT OUT on port: **spike** + +: IF v < thresh THEN +:    **spiking** = 0 + + + + + +**Derived Variables** + : **iChannels** = populations[*]->i(reduce method: add) + : **iCa** = populations[ion='ca']->i(reduce method: add) (exposed as **iCa**) + : **caConc** = concentrationModels[species='ca']->concentration(reduce method: add) (exposed as **caConc**) + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iMemb** = iChannels + iSyn (exposed as **iMemb**) + + + + + + +**Time Derivatives** + : d **v** /dt = iMemb / C + + +```` +````` + +(schema:distal)= + +## distal + + + + +extends {ref}`schema:point3dwithdiam` + + + +Point on a {ref}`schema:segment` furthest from the soma. Should always be present in the description of a {ref}`schema:segment`, unlike {ref}`schema:proximal`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**diameter**$ Diameter of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless +**x**$ x coordinate of the point. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless +**y**$ y coordinate of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless +**z**$ z coordinate of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**radius**$ A dimensional quantity given by half the _diameter. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **radius** = MICRON * diameter / 2 +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**xLength**$ A version of _x with dimension length. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **xLength** = MICRON * x +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**yLength**$ A version of _y with dimension length. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **yLength** = MICRON * y +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**zLength**$ A version of _z with dimension length. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **zLength** = MICRON * z + +```` + + +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:proximal)= + +## proximal + + + + +extends {ref}`schema:point3dwithdiam` + + + +Point on a {ref}`schema:segment` closest to the soma. Note, the proximal point can be omitted, and in this case is defined as being the point **fractionAlong** between the proximal and {ref}`schema:distal` point of the {ref}`schema:parent`, i.e. if **fractionAlong** = 1 ( as it is by default ) it will be the **distal** on the parent, or if **fractionAlong** = 0, it will be the proximal point. If between 0 and 1, it is the linear interpolation between the two points. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**diameter**$ Diameter of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless +**x**$ x coordinate of the point. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless +**y**$ y coordinate of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless +**z**$ z coordinate of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. *(from {ref}`schema:point3dwithdiam`)* $Dimensionless + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**radius**$ A dimensional quantity given by half the _diameter. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **radius** = MICRON * diameter / 2 +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**xLength**$ A version of _x with dimension length. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **xLength** = MICRON * x +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**yLength**$ A version of _y with dimension length. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **yLength** = MICRON * y +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**zLength**$ A version of _z with dimension length. *(from {ref}`schema:point3dwithdiam`)* ${ref}`schema:dimensions:length` +``` +   **zLength** = MICRON * z + +```` + + +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:parent)= + +## parent + + + + +Specifies the {ref}`schema:segment` which is this segment's parent. The **fractionAlong** specifies where it is connected, usually 1 ( the default value ), meaning the {ref}`schema:distal` point of the parent, or 0, meaning the {ref}`schema:proximal` point. If it is between these, a linear interpolation between the 2 points should be used. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segment**$ The id of the parent segment +**fractionAlong**$ The fraction along the the parent segment at which this segment is attached. For usage see _proximal_ + +```` + + +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:segment)= + +## segment + + + + +A segment defines the smallest unit within a possibly branching structure ( {ref}`schema:morphology` ), such as a dendrite or axon. Its **id** should be a nonnegative integer ( usually soma/root = 0 ). Its end points are given by the {ref}`schema:proximal` and {ref}`schema:distal` points. The {ref}`schema:proximal` point can be omitted, usually because it is the same as a point on the {ref}`schema:parent` segment, see {ref}`schema:proximal` for details. {ref}`schema:parent` specifies the parent segment. The first segment of a {ref}`schema:cell` ( with no {ref}`schema:parent` ) usually represents the soma. The shape is normally a cylinder ( radii of the {ref}`schema:proximal` and {ref}`schema:distal` equal, but positions different ) or a conical frustum ( radii and positions different ). If the x, y, x positions of the {ref}`schema:proximal` and {ref}`schema:distal` are equal, the segment can be interpreted as a sphere, and in this case the radii of these points must be equal. NOTE: LEMS does not yet support multicompartmental modelling, so the Dynamics here is only appropriate for single compartment modelling. + + +`````{tab-set} +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**LEN** = 1m$ $ {ref}`schema:dimensions:length` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**name**$ An optional name for the segment. Convenient for providing a suitable variable name for generated code, e.g. soma, dend0 + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**parent**$ $ {ref}`schema:parent` +**distal**$ $ {ref}`schema:distal` +**proximal**$ $ {ref}`schema:proximal` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**length**$ ${ref}`schema:dimensions:length` +**radDist**$ ${ref}`schema:dimensions:length` +**surfaceArea**$ ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **radDist** = distal->radius (exposed as **radDist**) + : **dx** = distal->xLength + : **dy** = distal->yLength + : **dz** = distal->zLength + : **px** = proximal->xLength + : **py** = proximal->yLength + : **pz** = proximal->zLength + : **length** = sqrt(((dx - px) * (dx - px) + (dy - py) * (dy - py) + (dz - pz) * (dz - pz))/(LEN * LEN)) * LEN (exposed as **length**) + + + + +**Conditional Derived Variables** + +: IF length = 0 * LEN THEN +:   **surfaceArea** = 4 \* radDist \* radDist \* 3.14159265  (exposed as **surfaceArea**) +: IF length > 0 * LEN THEN +:   **surfaceArea** = 2 \* radDist \* 3.14159265 \* length  (exposed as **surfaceArea**) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Segment + +variable = Segment( + id: 'a NonNegativeInteger (required)' = None, + name: 'a string (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + parent: 'a SegmentParent (optional)' = None, + proximal: 'a Point3DWithDiam (optional)' = None, + distal: 'a Point3DWithDiam (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + +``` +```{code-block} xml + + + + + +``` +```{code-block} xml + + + + + +``` +```` +````` + +(schema:segmentgroup)= + +## segmentGroup + + + + +A method to describe a group of {ref}`schema:segment`s in a {ref}`schema:morphology`, e.g. soma_group, dendrite_group, axon_group. While a name is useful to describe the group, the **neuroLexId** attribute can be used to explicitly specify the meaning of the group, e.g. sao1044911821 for 'Neuronal Cell Body', sao1211023249 for 'Dendrite'. The {ref}`schema:segment`s in this group can be specified as: a list of individual {ref}`schema:member` segments; a {ref}`schema:path`, all of the segments along which should be included; a {ref}`schema:subtree` of the {ref}`schema:cell` to include; other segmentGroups to {ref}`schema:include` ( so all segments from those get included here ). An {ref}`schema:inhomogeneousparameter` can be defined on the region of the cell specified by this group ( see {ref}`schema:variableparameter` for usage ). + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**neuroLexId**$ An id string for pointing to an entry in the NeuroLex ontology. Use of this attribute is a shorthand for a full RDF based reference to the MIRIAM Resource urn:miriam:neurolex, with an bqbiol:is qualifier. + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**notes**$ $ {ref}`schema:notes` +**annotation**$ $ {ref}`schema:annotation` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**property**$ $ {ref}`schema:property` +**members**$ $ {ref}`schema:member` +**paths**$ $ {ref}`schema:path` +**subTrees**$ $ {ref}`schema:subtree` +**includes**$ $ {ref}`schema:include` +**inhomogeneousParameter**$ $ {ref}`schema:inhomogeneousparameter` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SegmentGroup + +variable = SegmentGroup( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + members: 'list of Member(s) (optional)' = None, + includes: 'list of Include(s) (optional)' = None, + paths: 'list of Path(s) (optional)' = None, + sub_trees: 'list of SubTree(s) (optional)' = None, + inhomogeneous_parameters: 'list of InhomogeneousParameter(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + +``` +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:member)= + +## member + + + + +A single identified **segment** which is part of the {ref}`schema:segmentgroup`. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segment**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Member + +variable = Member( + segments: 'a NonNegativeInteger (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:from)= + +## from + + + + +In a {ref}`schema:path` or {ref}`schema:subtree`, specifies which **segment** ( inclusive ) from which to calculate the {ref}`schema:segmentgroup`. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segment**$ + +```` + + +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:to)= + +## to + + + + +In a {ref}`schema:path`, specifies which **segment** ( inclusive ) up to which to calculate the {ref}`schema:segmentgroup`. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segment**$ + +```` + + +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:include)= + +## include + + + + +Include all members of another {ref}`schema:segmentgroup` in this group. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**href**$ TODO: fix this!!! This is needed here, since include is used to include external nml files!! +**segmentGroup**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Include + +variable = Include( + segment_groups: 'a NmlId (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:path)= + +## path + + + + +Include all the {ref}`schema:segment`s between those specified by {ref}`schema:from` and {ref}`schema:to`, inclusive. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**from**$ $ {ref}`schema:from` +**to**$ $ {ref}`schema:to` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Path + +variable = Path( + from_: 'a SegmentEndPoint (optional)' = None, + to: 'a SegmentEndPoint (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + +``` +```` +````` + +(schema:subtree)= + +## subTree + + + + +Include all the {ref}`schema:segment`s distal to that specified by {ref}`schema:from` in the {ref}`schema:segmentgroup`. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**from**$ $ {ref}`schema:from` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SubTree + +variable = SubTree( + from_: 'a SegmentEndPoint (optional)' = None, + to: 'a SegmentEndPoint (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```` +````` + +(schema:inhomogeneousparameter)= + +## inhomogeneousParameter + + + + +An inhomogeneous parameter specified across the {ref}`schema:segmentgroup` ( see {ref}`schema:variableparameter` for usage ). + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**variable**$ +**metric**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**proximal**$ $ {ref}`schema:proximaldetails` +**distal**$ $ {ref}`schema:distaldetails` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import InhomogeneousParameter + +variable = InhomogeneousParameter( + id: 'a NmlId (required)' = None, + variable: 'a string (required)' = None, + metric: 'a Metric (required)' = None, + proximal: 'a ProximalDetails (optional)' = None, + distal: 'a DistalDetails (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + +``` +```{code-block} xml + +``` +```` +````` + +(schema:proximaldetails)= + +## proximalDetails + + + + +What to do at the proximal point when creating an inhomogeneous parameter. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**translationStart**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ProximalDetails + +variable = ProximalDetails( + translation_start: 'a double (required)' = None, +) +``` +```` +````` + +(schema:distaldetails)= + +## distalDetails + + + + +What to do at the distal point when creating an inhomogeneous parameter. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**normalizationEnd**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import DistalDetails + +variable = DistalDetails( + normalization_end: 'a double (required)' = None, +) +``` +```` +````` + +(schema:morphology)= + +## morphology + + + + +The collection of {ref}`schema:segment`s which specify the 3D structure of the cell, along with a number of {ref}`schema:segmentgroup`s. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**segments**$ $ {ref}`schema:segment` +**segmentGroups**$ $ {ref}`schema:segmentgroup` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Morphology + +variable = Morphology( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + segments: 'list of Segment(s) (required)' = None, + segment_groups: 'list of SegmentGroup(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +```{code-block} xml + + + + + + + + +``` +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +```` +````` + +(schema:specificcapacitance)= + +## specificCapacitance + + + + +Capacitance per unit area. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**value**$ ${ref}`schema:dimensions:specificCapacitance` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**specCap**$ ${ref}`schema:dimensions:specificCapacitance` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **specCap** = value (exposed as **specCap**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpecificCapacitance + +variable = SpecificCapacitance( + value: 'a Nml2Quantity_specificCapacitance (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:initmembpotential)= + +## initMembPotential + + + + +Explicitly set initial membrane potential for the cell. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**value**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import InitMembPotential + +variable = InitMembPotential( + value: 'a Nml2Quantity_voltage (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:spikethresh)= + +## spikeThresh + + + + +Membrane potential at which to emit a spiking event. Note, usually the spiking event will not be emitted again until the membrane potential has fallen below this value and rises again to cross it in a positive direction. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**value**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeThresh + +variable = SpikeThresh( + value: 'a Nml2Quantity_voltage (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:membraneproperties)= + +## membraneProperties + + + + +Properties specific to the membrane, such as the **populations** of channels, **channelDensities,** **specificCapacitance,** etc. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**initMembPotential**$ $ {ref}`schema:initmembpotential` +**spikeThresh**$ $ {ref}`schema:spikethresh` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**specificCapacitances**$ $ {ref}`schema:specificcapacitance` +**populations**$ $ {ref}`schema:basechannelpopulation` +**channelDensities**$ $ {ref}`schema:basechanneldensity` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iCa**$ ${ref}`schema:dimensions:current` +**totChanCurrent**$ ${ref}`schema:dimensions:current` +**totSpecCap**$ ${ref}`schema:dimensions:specificCapacitance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**surfaceArea**$ ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **totSpecCap** = specificCapacitances[*]->specCap(reduce method: add) (exposed as **totSpecCap**) + : **totChanPopCurrent** = populations[*]->i(reduce method: add) + : **totChanDensCurrentDensity** = channelDensities[*]->iDensity(reduce method: add) + : **totChanCurrent** = totChanPopCurrent + (totChanDensCurrentDensity * surfaceArea) (exposed as **totChanCurrent**) + : **totChanPopCurrentCa** = populations[ion='ca']->i(reduce method: add) + : **totChanDensCurrentDensityCa** = channelDensities[ion='ca']->iDensity(reduce method: add) + : **iCa** = totChanPopCurrentCa + (totChanDensCurrentDensityCa * surfaceArea) (exposed as **iCa**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import MembraneProperties + +variable = MembraneProperties( + channel_populations: 'list of ChannelPopulation(s) (optional)' = None, + channel_densities: 'list of ChannelDensity(s) (optional)' = None, + channel_density_v_shifts: 'list of ChannelDensityVShift(s) (optional)' = None, + channel_density_nernsts: 'list of ChannelDensityNernst(s) (optional)' = None, + channel_density_ghks: 'list of ChannelDensityGHK(s) (optional)' = None, + channel_density_ghk2s: 'list of ChannelDensityGHK2(s) (optional)' = None, + channel_density_non_uniforms: 'list of ChannelDensityNonUniform(s) (optional)' = None, + channel_density_non_uniform_nernsts: 'list of ChannelDensityNonUniformNernst(s) (optional)' = None, + channel_density_non_uniform_ghks: 'list of ChannelDensityNonUniformGHK(s) (optional)' = None, + spike_threshes: 'list of SpikeThresh(s) (optional)' = None, + specific_capacitances: 'list of SpecificCapacitance(s) (optional)' = None, + init_memb_potentials: 'list of InitMembPotential(s) (optional)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + +``` +```{code-block} xml + + + + + + + +``` +```{code-block} xml + + + + + + + + +``` +```` +````` + +(schema:membraneproperties2capools)= + +## membraneProperties2CaPools + + + + +extends {ref}`schema:membraneproperties` + + + +Variant of membraneProperties with 2 independent Ca pools. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**initMembPotential**$ $ {ref}`schema:initmembpotential` +**spikeThresh**$ $ {ref}`schema:spikethresh` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**specificCapacitances**$ $ {ref}`schema:specificcapacitance` +**populations**$ $ {ref}`schema:basechannelpopulation` +**channelDensities**$ $ {ref}`schema:basechanneldensity` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iCa**$ *(from {ref}`schema:membraneproperties`)* ${ref}`schema:dimensions:current` +**iCa2**$ ${ref}`schema:dimensions:current` +**totChanCurrent**$ *(from {ref}`schema:membraneproperties`)* ${ref}`schema:dimensions:current` +**totSpecCap**$ *(from {ref}`schema:membraneproperties`)* ${ref}`schema:dimensions:specificCapacitance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**surfaceArea**$ ${ref}`schema:dimensions:area` +**surfaceArea**$ *(from {ref}`schema:membraneproperties`)* ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **totSpecCap** = specificCapacitances[*]->specCap(reduce method: add) (exposed as **totSpecCap**) + : **totChanPopCurrent** = populations[*]->i(reduce method: add) + : **totChanDensCurrentDensity** = channelDensities[*]->iDensity(reduce method: add) + : **totChanCurrent** = totChanPopCurrent + (totChanDensCurrentDensity * surfaceArea) (exposed as **totChanCurrent**) + : **totChanPopCurrentCa** = populations[ion='ca']->i(reduce method: add) + : **totChanDensCurrentDensityCa** = channelDensities[ion='ca']->iDensity(reduce method: add) + : **iCa** = totChanPopCurrentCa + (totChanDensCurrentDensityCa * surfaceArea) (exposed as **iCa**) + : **totChanPopCurrentCa2** = populations[ion='ca2']->i(reduce method: add) + : **totChanDensCurrentDensityCa2** = channelDensities[ion='ca2']->iDensity(reduce method: add) + : **iCa2** = totChanPopCurrentCa2 + (totChanDensCurrentDensityCa2 * surfaceArea) (exposed as **iCa2**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import MembraneProperties2CaPools + +variable = MembraneProperties2CaPools( + channel_populations: 'list of ChannelPopulation(s) (optional)' = None, + channel_densities: 'list of ChannelDensity(s) (optional)' = None, + channel_density_v_shifts: 'list of ChannelDensityVShift(s) (optional)' = None, + channel_density_nernsts: 'list of ChannelDensityNernst(s) (optional)' = None, + channel_density_ghks: 'list of ChannelDensityGHK(s) (optional)' = None, + channel_density_ghk2s: 'list of ChannelDensityGHK2(s) (optional)' = None, + channel_density_non_uniforms: 'list of ChannelDensityNonUniform(s) (optional)' = None, + channel_density_non_uniform_nernsts: 'list of ChannelDensityNonUniformNernst(s) (optional)' = None, + channel_density_non_uniform_ghks: 'list of ChannelDensityNonUniformGHK(s) (optional)' = None, + spike_threshes: 'list of SpikeThresh(s) (optional)' = None, + specific_capacitances: 'list of SpecificCapacitance(s) (optional)' = None, + init_memb_potentials: 'list of InitMembPotential(s) (optional)' = None, + channel_density_nernst_ca2s: 'list of ChannelDensityNernstCa2(s) (optional)' = None, +) +``` +```` +````` + +(schema:biophysicalproperties)= + +## biophysicalProperties + + + + +The biophysical properties of the {ref}`schema:cell`, including the {ref}`schema:membraneproperties` and the {ref}`schema:intracellularproperties`. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**membraneProperties**$ $ {ref}`schema:membraneproperties` +**intracellularProperties**$ $ {ref}`schema:intracellularproperties` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**totSpecCap**$ ${ref}`schema:dimensions:specificCapacitance` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **totSpecCap** = membraneProperties->totSpecCap (exposed as **totSpecCap**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BiophysicalProperties + +variable = BiophysicalProperties( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + membrane_properties: 'a MembraneProperties (required)' = None, + intracellular_properties: 'a IntracellularProperties (optional)' = None, + extracellular_properties: 'a ExtracellularProperties (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + + + + + + +``` +```{code-block} xml + + + + + + + + + + + + + +``` +```{code-block} xml + + + + + + + + + + + + + +``` +```` +````` + +(schema:biophysicalproperties2capools)= + +## biophysicalProperties2CaPools + + + + +The biophysical properties of the {ref}`schema:cell`, including the {ref}`schema:membraneproperties2capools` and the {ref}`schema:intracellularproperties2capools` for a cell with two Ca pools. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**membraneProperties2CaPools**$ $ {ref}`schema:membraneproperties2capools` +**intracellularProperties2CaPools**$ $ {ref}`schema:intracellularproperties2capools` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**totSpecCap**$ ${ref}`schema:dimensions:specificCapacitance` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **totSpecCap** = membraneProperties2CaPools->totSpecCap (exposed as **totSpecCap**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BiophysicalProperties2CaPools + +variable = BiophysicalProperties2CaPools( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + membrane_properties2_ca_pools: 'a MembraneProperties2CaPools (required)' = None, + intracellular_properties2_ca_pools: 'a IntracellularProperties2CaPools (optional)' = None, + extracellular_properties: 'a ExtracellularProperties (optional)' = None, +) +``` +```` +````` + +(schema:intracellularproperties)= + +## intracellularProperties + + + + +Biophysical properties related to the intracellular space within the {ref}`schema:cell`, such as the {ref}`schema:resistivity` and the list of ionic {ref}`schema:species` present. **caConc** and **caConcExt** are explicitly exposed here to facilitate accessing these values from other Components, even though **caConcExt** is clearly not an intracellular property. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**resistivity**$ $ {ref}`schema:resistivity` +**speciesList**$ $ {ref}`schema:species` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **caConc** = speciesList[ion='ca']->concentration(reduce method: add) (exposed as **caConc**) + : **caConcExt** = speciesList[ion='ca']->extConcentration(reduce method: add) (exposed as **caConcExt**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IntracellularProperties + +variable = IntracellularProperties( + species: 'list of Species(s) (optional)' = None, + resistivities: 'list of Resistivity(s) (optional)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:intracellularproperties2capools)= + +## intracellularProperties2CaPools + + + + +extends {ref}`schema:intracellularproperties` + + + +Variant of intracellularProperties with 2 independent Ca pools. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**speciesList**$ $ {ref}`schema:species` +**resistivity**$ $ {ref}`schema:resistivity` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ *(from {ref}`schema:intracellularproperties`)* ${ref}`schema:dimensions:concentration` +**caConc2**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ *(from {ref}`schema:intracellularproperties`)* ${ref}`schema:dimensions:concentration` +**caConcExt2**$ ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **caConc2** = speciesList[ion='ca2']->concentration(reduce method: add) (exposed as **caConc2**) + : **caConcExt2** = speciesList[ion='ca2']->extConcentration(reduce method: add) (exposed as **caConcExt2**) + : **caConc** = speciesList[ion='ca']->concentration(reduce method: add) (exposed as **caConc**) + : **caConcExt** = speciesList[ion='ca']->extConcentration(reduce method: add) (exposed as **caConcExt**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IntracellularProperties2CaPools + +variable = IntracellularProperties2CaPools( + species: 'list of Species(s) (optional)' = None, + resistivities: 'list of Resistivity(s) (optional)' = None, +) +``` +```` +````` + +(schema:resistivity)= + +## resistivity + + + + +The resistivity, or specific axial resistance, of the cytoplasm. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**value**$ ${ref}`schema:dimensions:resistivity` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentGroup**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Resistivity + +variable = Resistivity( + value: 'a Nml2Quantity_resistivity (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:concentrationmodel)= + +## concentrationModel + + + + +Base for any model of an **ion** concentration which changes with time. Internal ( **concentration** ) and external ( **extConcentration** ) values for the concentration of the ion are given. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**ion**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**concentration**$ ${ref}`schema:dimensions:concentration` +**extConcentration**$ ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**initialConcentration**$ ${ref}`schema:dimensions:concentration` +**initialExtConcentration**$ ${ref}`schema:dimensions:concentration` +**surfaceArea**$ ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **concentration**: {ref}`schema:dimensions:concentration`  (exposed as **concentration**) +: **extConcentration**: {ref}`schema:dimensions:concentration`  (exposed as **extConcentration**) + + + + + + + + + +**On Start** +: **concentration** = initialConcentration +: **extConcentration** = initialExtConcentration + + + + + + + + +```` +````` + +(schema:decayingpoolconcentrationmodel)= + +## decayingPoolConcentrationModel + + + + +extends {ref}`schema:concentrationmodel` + + + +Model of an intracellular buffering mechanism for **ion** ( currently hard Coded to be calcium, due to requirement for **iCa** ) which has a baseline level **restingConc** and tends to this value with time course **decayConstant.** The ion is assumed to occupy a shell inside the membrane of thickness **shellThickness.**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**decayConstant**$ ${ref}`schema:dimensions:time` +**restingConc**$ ${ref}`schema:dimensions:concentration` +**shellThickness**$ ${ref}`schema:dimensions:length` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**Faraday** = 96485.3C_per_mol$ $ {ref}`schema:dimensions:charge_per_mole` +**AREA_SCALE** = 1m2$ $ {ref}`schema:dimensions:area` +**LENGTH_SCALE** = 1m$ $ {ref}`schema:dimensions:length` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**ion**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**concentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**extConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iCa**$ ${ref}`schema:dimensions:current` +**initialConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**initialExtConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**surfaceArea**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **concentration**: {ref}`schema:dimensions:concentration`  (exposed as **concentration**) +: **extConcentration**: {ref}`schema:dimensions:concentration`  (exposed as **extConcentration**) + + + + + + + + + +**On Start** +: **concentration** = initialConcentration +: **extConcentration** = initialExtConcentration + + + +**On Conditions** + +: IF concentration < 0 THEN +:    **concentration** = 0 + + + + + +**Derived Variables** + : **effectiveRadius** = LENGTH_SCALE * sqrt(surfaceArea/(AREA_SCALE * (4 * 3.14159))) + : **innerRadius** = effectiveRadius - shellThickness + : **shellVolume** = (4 * (effectiveRadius * effectiveRadius * effectiveRadius) * 3.14159 / 3) - (4 * (innerRadius * innerRadius * innerRadius) * 3.14159 / 3) + + + + + + +**Time Derivatives** + : d **concentration** /dt = iCa / (2 * Faraday * shellVolume) - ((concentration - restingConc) / decayConstant) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import DecayingPoolConcentrationModel + +variable = DecayingPoolConcentrationModel( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + ion: 'a NmlId (required)' = None, + resting_conc: 'a Nml2Quantity_concentration (required)' = None, + decay_constant: 'a Nml2Quantity_time (required)' = None, + shell_thickness: 'a Nml2Quantity_length (required)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:fixedfactorconcentrationmodel)= + +## fixedFactorConcentrationModel + + + + +extends {ref}`schema:concentrationmodel` + + + +Model of buffering of concentration of an ion ( currently hard coded to be calcium, due to requirement for **iCa** ) which has a baseline level **restingConc** and tends to this value with time course **decayConstant.** A fixed factor **rho** is used to scale the incoming current *independently of the size of the compartment* to produce a concentration change. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**decayConstant**$ ${ref}`schema:dimensions:time` +**restingConc**$ ${ref}`schema:dimensions:concentration` +**rho**$ ${ref}`schema:dimensions:rho_factor` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**ion**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**concentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**extConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iCa**$ ${ref}`schema:dimensions:current` +**initialConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**initialExtConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**surfaceArea**$ ${ref}`schema:dimensions:area` +**surfaceArea**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **concentration**: {ref}`schema:dimensions:concentration`  (exposed as **concentration**) +: **extConcentration**: {ref}`schema:dimensions:concentration`  (exposed as **extConcentration**) + + + + + + + + + +**On Start** +: **concentration** = initialConcentration +: **extConcentration** = initialExtConcentration + + + +**On Conditions** + +: IF concentration < 0 THEN +:    **concentration** = 0 + + + + + + + + +**Time Derivatives** + : d **concentration** /dt = (iCa/surfaceArea) * rho - ((concentration - restingConc) / decayConstant) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import FixedFactorConcentrationModel + +variable = FixedFactorConcentrationModel( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + ion: 'a NmlId (required)' = None, + resting_conc: 'a Nml2Quantity_concentration (required)' = None, + decay_constant: 'a Nml2Quantity_time (required)' = None, + rho: 'a Nml2Quantity_rhoFactor (required)' = None, +) +``` +```` +````` + +(schema:fixedfactorconcentrationmodeltraub)= + +## fixedFactorConcentrationModelTraub + + + + +extends {ref}`schema:concentrationmodel` + + + +Model of buffering of concentration of an ion ( currently hard coded to be calcium, due to requirement for **iCa** ) which has a baseline level **restingConc** and tends to this value with time course 1 / **beta.** A fixed factor **phi** is used to scale the incoming current *independently of the size of the compartment* to produce a concentration change. Not recommended for use in models other than Traub et al. 2005! + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**beta**$ ${ref}`schema:dimensions:per_time` +**phi**$ ${ref}`schema:dimensions:rho_factor` +**restingConc**$ ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**species**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**concentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**extConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iCa**$ ${ref}`schema:dimensions:current` +**initialConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**initialExtConcentration**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:concentration` +**surfaceArea**$ ${ref}`schema:dimensions:area` +**surfaceArea**$ *(from {ref}`schema:concentrationmodel`)* ${ref}`schema:dimensions:area` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **concentration**: {ref}`schema:dimensions:concentration`  (exposed as **concentration**) +: **extConcentration**: {ref}`schema:dimensions:concentration`  (exposed as **extConcentration**) + + + + + + + + + +**On Start** +: **concentration** = initialConcentration +: **extConcentration** = initialExtConcentration + + + +**On Conditions** + +: IF concentration < 0 THEN +:    **concentration** = 0 + + + + + + + + +**Time Derivatives** + : d **concentration** /dt = (iCa/surfaceArea) * 1e-9 * phi - ((concentration - restingConc) * beta) + + +```` +````` + +(schema:species)= + +## species + + + + +Description of a chemical species identified by **ion,** which has internal, **concentration,** and external, **extConcentration** values for its concentration. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**initialConcentration**$ ${ref}`schema:dimensions:concentration` +**initialExtConcentration**$ ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**ion**$ +**segmentGroup**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**concentrationModel**$ $ {ref}`schema:concentrationmodel` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**concentration**$ ${ref}`schema:dimensions:concentration` +**extConcentration**$ ${ref}`schema:dimensions:concentration` + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: CHILD INSTANCE: **concentrationModel** + + + + + + + + + +**Derived Variables** + : **concentration** = concentrationModel->concentration (exposed as **concentration**) + : **extConcentration** = concentrationModel->extConcentration (exposed as **extConcentration**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Species + +variable = Species( + id: 'a NmlId (required)' = None, + concentration_model: 'a NmlId (required)' = None, + ion: 'a NmlId (optional)' = None, + initial_concentration: 'a Nml2Quantity_concentration (required)' = None, + initial_ext_concentration: 'a Nml2Quantity_concentration (required)' = None, + segment_groups: 'a NmlId (optional)' = 'all', +) +``` +```` +````` + +(schema:cell)= + +## cell + + + + +extends *{ref}`schema:basecellmembpot`* + + + +Cell with {ref}`schema:segment`s specified in a {ref}`schema:morphology` element along with details on its {ref}`schema:biophysicalproperties`. NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v** of this cell represents the membrane potential in that isopotential segment. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**neuroLexId**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**morphology**$ Should only be used if morphology element is outside the cell. This points to the id of the morphology. $ {ref}`schema:morphology` +**biophysicalProperties**$ Should only be used if biophysicalProperties element is outside the cell. This points to the id of the biophysicalProperties $ {ref}`schema:biophysicalproperties` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ ${ref}`schema:dimensions:concentration` +**iCa**$ ${ref}`schema:dimensions:current` +**iChannels**$ ${ref}`schema:dimensions:current` +**iSyn**$ ${ref}`schema:dimensions:current` +**spiking**$ $Dimensionless +**surfaceArea**$ ${ref}`schema:dimensions:area` +**totSpecCap**$ ${ref}`schema:dimensions:specificCapacitance` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **spiking**: Dimensionless  (exposed as **spiking**) + + + + + + + + + +**On Start** +: **spiking** = 0 +: **v** = initMembPot + + + +**On Conditions** + +: IF v > thresh AND spiking < 0.5 THEN +:    **spiking** = 1 +:    EVENT OUT on port: **spike** + +: IF v < thresh THEN +:    **spiking** = 0 + + + + + +**Derived Variables** + : **initMembPot** = biophysicalProperties->membraneProperties->initMembPotential->value + : **thresh** = biophysicalProperties->membraneProperties->spikeThresh->value + : **surfaceArea** = morphology->segments[*]->surfaceArea(reduce method: add) (exposed as **surfaceArea**) + : **totSpecCap** = biophysicalProperties->totSpecCap (exposed as **totSpecCap**) + : **totCap** = totSpecCap * surfaceArea + : **iChannels** = biophysicalProperties->membraneProperties->totChanCurrent (exposed as **iChannels**) + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iCa** = biophysicalProperties->membraneProperties->iCa (exposed as **iCa**) + : **caConc** = biophysicalProperties->intracellularProperties->caConc (exposed as **caConc**) + : **caConcExt** = biophysicalProperties->intracellularProperties->caConcExt (exposed as **caConcExt**) + + + + + + +**Time Derivatives** + : d **v** /dt = (iChannels + iSyn) / totCap + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Cell + +variable = Cell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + morphology_attr: 'a NmlId (optional)' = None, + biophysical_properties_attr: 'a NmlId (optional)' = None, + morphology: 'a Morphology (optional)' = None, + biophysical_properties: 'a BiophysicalProperties (optional)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + A Simple Spiking cell for testing purposes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +```{code-block} xml + +``` +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +```` +````` + +(schema:cell2capools)= + +## cell2CaPools + + + + +extends {ref}`schema:cell` + + + +Variant of cell with two independent Ca2+ pools. Cell with {ref}`schema:segment`s specified in a {ref}`schema:morphology` element along with details on its {ref}`schema:biophysicalproperties`. NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v** of this cell represents the membrane potential in that isopotential segment. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**neuroLexId**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**biophysicalProperties2CaPools**$ $ {ref}`schema:biophysicalproperties2capools` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:concentration` +**caConc2**$ ${ref}`schema:dimensions:concentration` +**caConcExt**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:concentration` +**caConcExt2**$ ${ref}`schema:dimensions:concentration` +**iCa**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:current` +**iCa2**$ ${ref}`schema:dimensions:current` +**iChannels**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:current` +**iSyn**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:current` +**spiking**$ *(from {ref}`schema:cell`)* $Dimensionless +**surfaceArea**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:area` +**totSpecCap**$ *(from {ref}`schema:cell`)* ${ref}`schema:dimensions:specificCapacitance` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **spiking**: Dimensionless  (exposed as **spiking**) + + + + + + + + + +**On Start** +: **spiking** = 0 +: **v** = initMembPot + + + +**On Conditions** + +: IF v > thresh AND spiking < 0.5 THEN +:    **spiking** = 1 +:    EVENT OUT on port: **spike** + +: IF v < thresh THEN +:    **spiking** = 0 + + + + + +**Derived Variables** + : **initMembPot** = biophysicalProperties2CaPools->membraneProperties2CaPools->initMembPotential->value + : **thresh** = biophysicalProperties2CaPools->membraneProperties2CaPools->spikeThresh->value + : **surfaceArea** = morphology->segments[*]->surfaceArea(reduce method: add) (exposed as **surfaceArea**) + : **totSpecCap** = biophysicalProperties2CaPools->totSpecCap (exposed as **totSpecCap**) + : **totCap** = totSpecCap * surfaceArea + : **iChannels** = biophysicalProperties2CaPools->membraneProperties2CaPools->totChanCurrent (exposed as **iChannels**) + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iCa** = biophysicalProperties2CaPools->membraneProperties2CaPools->iCa (exposed as **iCa**) + : **caConc** = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConc (exposed as **caConc**) + : **caConcExt** = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConcExt (exposed as **caConcExt**) + : **iCa2** = biophysicalProperties2CaPools->membraneProperties2CaPools->iCa2 (exposed as **iCa2**) + : **caConc2** = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConc2 (exposed as **caConc2**) + : **caConcExt2** = biophysicalProperties2CaPools->intracellularProperties2CaPools->caConcExt2 (exposed as **caConcExt2**) + + + + + + +**Time Derivatives** + : d **v** /dt = (iChannels + iSyn) / totCap + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Cell2CaPools + +variable = Cell2CaPools( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + morphology_attr: 'a NmlId (optional)' = None, + biophysical_properties_attr: 'a NmlId (optional)' = None, + morphology: 'a Morphology (optional)' = None, + biophysical_properties: 'a BiophysicalProperties (optional)' = None, + biophysical_properties2_ca_pools: 'a BiophysicalProperties2CaPools (optional)' = None, +) +``` +```` +````` + +(schema:basecellmembpotcap)= + +## *baseCellMembPotCap* + + + + +extends *{ref}`schema:basecellmembpot`* + + + +Any cell with a membrane potential **v** with voltage units and a membrane capacitance **C.** Also defines exposed value **iSyn** for current due to external synapses and **iMemb** for total transmembrane current ( usually channel currents plus **iSyn** ). + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane ${ref}`schema:dimensions:capacitance` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseCellMembPotCap + +variable = BaseCellMembPotCap( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + C: 'a Nml2Quantity_capacitance (required)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:baseiaf)= + +## *baseIaf* + + + + +extends *{ref}`schema:basecellmembpot`* + + + +Base ComponentType for an integrate and fire cell which emits a spiking event at membrane potential **thresh** and and resets to **reset**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**reset**$ The value the membrane potential is reset to on spiking ${ref}`schema:dimensions:voltage` +**thresh**$ The membrane potential at which to emit a spiking event and reset voltage ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` +````` + +(schema:iaftaucell)= + +## iafTauCell + + + + +extends *{ref}`schema:baseiaf`* + + + +Integrate and fire cell which returns to its leak reversal potential of **leakReversal** with a time constant **tau**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**leakReversal**$ ${ref}`schema:dimensions:voltage` +**reset**$ The value the membrane potential is reset to on spiking *(from {ref}`schema:baseiaf`)* ${ref}`schema:dimensions:voltage` +**tau**$ ${ref}`schema:dimensions:time` +**thresh**$ The membrane potential at which to emit a spiking event and reset voltage *(from {ref}`schema:baseiaf`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) + + + + + + + + + +**On Start** +: **v** = leakReversal + + + +**On Conditions** + +: IF v > thresh THEN +:    **v** = reset +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **v** /dt = (leakReversal - v) / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IafTauCell + +variable = IafTauCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + leak_reversal: 'a Nml2Quantity_voltage (required)' = None, + thresh: 'a Nml2Quantity_voltage (required)' = None, + reset: 'a Nml2Quantity_voltage (required)' = None, + tau: 'a Nml2Quantity_time (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:iaftaurefcell)= + +## iafTauRefCell + + + + +extends {ref}`schema:iaftaucell` + + + +Integrate and fire cell which returns to its leak reversal potential of **leakReversal** with a time course **tau.** It has a refractory period of **refract** after spiking. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**leakReversal**$ *(from {ref}`schema:iaftaucell`)* ${ref}`schema:dimensions:voltage` +**refract**$ ${ref}`schema:dimensions:time` +**reset**$ The value the membrane potential is reset to on spiking *(from {ref}`schema:baseiaf`)* ${ref}`schema:dimensions:voltage` +**tau**$ *(from {ref}`schema:iaftaucell`)* ${ref}`schema:dimensions:time` +**thresh**$ The membrane potential at which to emit a spiking event and reset voltage *(from {ref}`schema:baseiaf`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = leakReversal + + + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = reset +: **On Conditions** +:    IF t > lastSpikeTime + refract THEN +:     TRANSITION to REGIME **integrating** + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > thresh THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (leakReversal - v) / tau +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IafTauRefCell + +variable = IafTauRefCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + leak_reversal: 'a Nml2Quantity_voltage (required)' = None, + thresh: 'a Nml2Quantity_voltage (required)' = None, + reset: 'a Nml2Quantity_voltage (required)' = None, + tau: 'a Nml2Quantity_time (required)' = None, + refract: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:baseiafcapcell)= + +## *baseIafCapCell* + + + + +extends *{ref}`schema:basecellmembpotcap`* + + + +Base Type for all Integrate and Fire cells with a capacitance **C,** threshold **thresh** and reset membrane potential **reset**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**reset**$ ${ref}`schema:dimensions:voltage` +**thresh**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` +````` + +(schema:iafcell)= + +## iafCell + + + + +extends *{ref}`schema:baseiafcapcell`* + + + +Integrate and fire cell with capacitance **C,** **leakConductance** and **leakReversal**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**leakConductance**$ ${ref}`schema:dimensions:conductance` +**leakReversal**$ ${ref}`schema:dimensions:voltage` +**reset**$ *(from {ref}`schema:baseiafcapcell`)* ${ref}`schema:dimensions:voltage` +**thresh**$ *(from {ref}`schema:baseiafcapcell`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) + + + + + + + + + +**On Start** +: **v** = leakReversal + + + +**On Conditions** + +: IF v > thresh THEN +:    **v** = reset +:    EVENT OUT on port: **spike** + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iMemb** = leakConductance * (leakReversal - v) + iSyn (exposed as **iMemb**) + + + + + + +**Time Derivatives** + : d **v** /dt = iMemb / C + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IafCell + +variable = IafCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + leak_reversal: 'a Nml2Quantity_voltage (required)' = None, + thresh: 'a Nml2Quantity_voltage (required)' = None, + reset: 'a Nml2Quantity_voltage (required)' = None, + C: 'a Nml2Quantity_capacitance (required)' = None, + leak_conductance: 'a Nml2Quantity_conductance (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:iafrefcell)= + +## iafRefCell + + + + +extends {ref}`schema:iafcell` + + + +Integrate and fire cell with capacitance **C,** **leakConductance,** **leakReversal** and refractory period **refract**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**leakConductance**$ *(from {ref}`schema:iafcell`)* ${ref}`schema:dimensions:conductance` +**leakReversal**$ *(from {ref}`schema:iafcell`)* ${ref}`schema:dimensions:voltage` +**refract**$ ${ref}`schema:dimensions:time` +**reset**$ *(from {ref}`schema:baseiafcapcell`)* ${ref}`schema:dimensions:voltage` +**thresh**$ *(from {ref}`schema:baseiafcapcell`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = leakReversal + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iMemb** = leakConductance * (leakReversal - v) + iSyn (exposed as **iMemb**) + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = reset +: **On Conditions** +:    IF t > lastSpikeTime + refract THEN +:     TRANSITION to REGIME **integrating** + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > thresh THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = iMemb / C +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IafRefCell + +variable = IafRefCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + leak_reversal: 'a Nml2Quantity_voltage (required)' = None, + thresh: 'a Nml2Quantity_voltage (required)' = None, + reset: 'a Nml2Quantity_voltage (required)' = None, + C: 'a Nml2Quantity_capacitance (required)' = None, + leak_conductance: 'a Nml2Quantity_conductance (required)' = None, + refract: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:izhikevichcell)= + +## izhikevichCell + + + + +extends *{ref}`schema:basecellmembpot`* + + + +Cell based on the 2003 model of Izhikevich, see http://izhikevich.org/publications/spikes.htm. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**a**$ Time scale of the recovery variable U $Dimensionless +**b**$ Sensitivity of U to the subthreshold fluctuations of the membrane potential V $Dimensionless +**c**$ After-spike reset value of V $Dimensionless +**d**$ After-spike increase to U $Dimensionless +**thresh**$ Spike threshold ${ref}`schema:dimensions:voltage` +**v0**$ Initial membrane potential ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MSEC** = 1ms$ $ {ref}`schema:dimensions:time` +**MVOLT** = 1mV$ $ {ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**U**$ Membrane recovery variable $Dimensionless +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrentdl` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **U**: Dimensionless  (exposed as **U**) + + + + + + + + + +**On Start** +: **v** = v0 +: **U** = v0 * b / MVOLT + + + +**On Conditions** + +: IF v > thresh THEN +:    **v** = c * MVOLT +:    **U** = U + d +:    EVENT OUT on port: **spike** + + + + + +**Derived Variables** + : **ISyn** = synapses[*]->I(reduce method: add) + + + + + + +**Time Derivatives** + : d **v** /dt = (0.04 * v^2 / MVOLT + 5 * v + (140.0 - U + ISyn) * MVOLT)/MSEC + : d **U** /dt = a * (b * v / MVOLT - U) / MSEC + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IzhikevichCell + +variable = IzhikevichCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + v0: 'a Nml2Quantity_voltage (required)' = None, + thresh: 'a Nml2Quantity_voltage (required)' = None, + a: 'a Nml2Quantity_none (required)' = None, + b: 'a Nml2Quantity_none (required)' = None, + c: 'a Nml2Quantity_none (required)' = None, + d: 'a Nml2Quantity_none (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:izhikevich2007cell)= + +## izhikevich2007Cell + + + + +extends *{ref}`schema:basecellmembpotcap`* + + + +Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**a**$ Time scale of recovery variable u ${ref}`schema:dimensions:per_time` +**b**$ Sensitivity of recovery variable u to subthreshold fluctuations of membrane potential v ${ref}`schema:dimensions:conductance` +**c**$ After-spike reset value of v ${ref}`schema:dimensions:voltage` +**d**$ After-spike increase to u ${ref}`schema:dimensions:current` +**k**$ ${ref}`schema:dimensions:conductance_per_voltage` +**v0**$ Initial membrane potential ${ref}`schema:dimensions:voltage` +**vpeak**$ Peak action potential value ${ref}`schema:dimensions:voltage` +**vr**$ Resting membrane potential ${ref}`schema:dimensions:voltage` +**vt**$ Spike threshold ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**u**$ Membrane recovery variable ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **u**: {ref}`schema:dimensions:current`  (exposed as **u**) + + + + + + + + + +**On Start** +: **v** = v0 +: **u** = 0 + + + +**On Conditions** + +: IF v > vpeak THEN +:    **v** = c +:    **u** = u + d +:    EVENT OUT on port: **spike** + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iMemb** = k * (v-vr) * (v-vt) + iSyn - u (exposed as **iMemb**) + + + + + + +**Time Derivatives** + : d **v** /dt = iMemb / C + : d **u** /dt = a * (b * (v-vr) - u) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Izhikevich2007Cell + +variable = Izhikevich2007Cell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + C: 'a Nml2Quantity_capacitance (required)' = None, + v0: 'a Nml2Quantity_voltage (required)' = None, + k: 'a Nml2Quantity_conductancePerVoltage (required)' = None, + vr: 'a Nml2Quantity_voltage (required)' = None, + vt: 'a Nml2Quantity_voltage (required)' = None, + vpeak: 'a Nml2Quantity_voltage (required)' = None, + a: 'a Nml2Quantity_pertime (required)' = None, + b: 'a Nml2Quantity_conductance (required)' = None, + c: 'a Nml2Quantity_voltage (required)' = None, + d: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:adexiafcell)= + +## adExIaFCell + + + + +extends *{ref}`schema:basecellmembpotcap`* + + + +Model based on Brette R and Gerstner W ( 2005 ) Adaptive Exponential Integrate-and-Fire Model as an Effective Description of Neuronal Activity. J Neurophysiol 94:3637-3642. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**EL**$ Leak reversal potential ${ref}`schema:dimensions:voltage` +**VT**$ Spike threshold ${ref}`schema:dimensions:voltage` +**a**$ Sub-threshold adaptation variable ${ref}`schema:dimensions:conductance` +**b**$ Spike-triggered adaptation variable ${ref}`schema:dimensions:current` +**delT**$ Slope factor ${ref}`schema:dimensions:voltage` +**gL**$ Leak conductance ${ref}`schema:dimensions:conductance` +**refract**$ Refractory period ${ref}`schema:dimensions:time` +**reset**$ Reset potential ${ref}`schema:dimensions:voltage` +**tauw**$ Adaptation time constant ${ref}`schema:dimensions:time` +**thresh**$ Spike detection threshold ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` +**w**$ Adaptation current ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **w**: {ref}`schema:dimensions:current`  (exposed as **w**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = EL +: **w** = 0 + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iMemb** = -1 * gL * (v - EL) + gL * delT * exp((v - VT) / delT) - w + iSyn (exposed as **iMemb**) + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = reset +:    **w** = w + b +: **On Conditions** +:    IF t > lastSpikeTime + refract THEN +:     TRANSITION to REGIME **integrating** +: **Time Derivatives** +:    d **w** /dt = (a * (v - EL) - w) / tauw + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > thresh THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = iMemb / C +:    d **w** /dt = (a * (v - EL) - w) / tauw +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import AdExIaFCell + +variable = AdExIaFCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + C: 'a Nml2Quantity_capacitance (required)' = None, + g_l: 'a Nml2Quantity_conductance (required)' = None, + EL: 'a Nml2Quantity_voltage (required)' = None, + reset: 'a Nml2Quantity_voltage (required)' = None, + VT: 'a Nml2Quantity_voltage (required)' = None, + thresh: 'a Nml2Quantity_voltage (required)' = None, + del_t: 'a Nml2Quantity_voltage (required)' = None, + tauw: 'a Nml2Quantity_time (required)' = None, + refract: 'a Nml2Quantity_time (required)' = None, + a: 'a Nml2Quantity_conductance (required)' = None, + b: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:fitzhughnagumocell)= + +## fitzHughNagumoCell + + + + +extends *{ref}`schema:basecellmembpotdl`* + + + +Simple dimensionless model of spiking cell from FitzHugh and Nagumo. Superseded by **fitzHughNagumo1969Cell** ( See https://github.com/NeuroML/NeuroML2/issues/42 ). + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SEC** = 1s$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**V**$ Membrane potential *(from {ref}`schema:basecellmembpotdl`)* $Dimensionless +**W**$ $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **V**: Dimensionless  (exposed as **V**) +: **W**: Dimensionless  (exposed as **W**) + + + + + + + + + + +**Time Derivatives** + : d **V** /dt = ( (V - ((V^3) / 3)) - W + I) / SEC + : d **W** /dt = (0.08 * (V + 0.7 - 0.8 * W)) / SEC + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import FitzHughNagumoCell + +variable = FitzHughNagumoCell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + I: 'a Nml2Quantity_none (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:pinskyrinzelca3cell)= + +## pinskyRinzelCA3Cell + + + + +extends *{ref}`schema:basecellmembpot`* + + + +Reduced CA3 cell model from Pinsky, P.F., Rinzel, J. Intrinsic and network rhythmogenesis in a reduced traub model for CA3 neurons. J Comput Neurosci 1, 39-60 ( 1994 ). See https://github.com/OpenSourceBrain/PinskyRinzelModel. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**alphac**$ $Dimensionless +**betac**$ $Dimensionless +**cm**$ ${ref}`schema:dimensions:specificCapacitance` +**eCa**$ ${ref}`schema:dimensions:voltage` +**eK**$ ${ref}`schema:dimensions:voltage` +**eL**$ ${ref}`schema:dimensions:voltage` +**eNa**$ ${ref}`schema:dimensions:voltage` +**gAmpa**$ ${ref}`schema:dimensions:conductanceDensity` +**gCa**$ ${ref}`schema:dimensions:conductanceDensity` +**gKC**$ ${ref}`schema:dimensions:conductanceDensity` +**gKahp**$ ${ref}`schema:dimensions:conductanceDensity` +**gKdr**$ ${ref}`schema:dimensions:conductanceDensity` +**gLd**$ ${ref}`schema:dimensions:conductanceDensity` +**gLs**$ ${ref}`schema:dimensions:conductanceDensity` +**gNa**$ ${ref}`schema:dimensions:conductanceDensity` +**gNmda**$ ${ref}`schema:dimensions:conductanceDensity` +**gc**$ ${ref}`schema:dimensions:conductanceDensity` +**iDend**$ ${ref}`schema:dimensions:currentDensity` +**iSoma**$ ${ref}`schema:dimensions:currentDensity` +**pp**$ $Dimensionless +**qd0**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MSEC** = 1 ms$ $ {ref}`schema:dimensions:time` +**MVOLT** = 1 mV$ $ {ref}`schema:dimensions:voltage` +**UAMP_PER_CM2** = 1 uA_per_cm2$ $ {ref}`schema:dimensions:currentDensity` +**Smax** = 125.0$ $ Dimensionless +**Vsyn** = 60.0 mV$ $ {ref}`schema:dimensions:voltage` +**betaqd** = 0.001$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**Cad**$ $Dimensionless +**ICad**$ ${ref}`schema:dimensions:currentDensity` +**Si**$ $Dimensionless +**Vd**$ Dendritic membrane potential ${ref}`schema:dimensions:voltage` +**Vs**$ Somatic membrane potential ${ref}`schema:dimensions:voltage` +**Wi**$ $Dimensionless +**cd**$ $Dimensionless +**hs**$ $Dimensionless +**ns**$ $Dimensionless +**qd**$ $Dimensionless +**sd**$ $Dimensionless +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **Vs**: {ref}`schema:dimensions:voltage`  (exposed as **Vs**) +: **Vd**: {ref}`schema:dimensions:voltage`  (exposed as **Vd**) +: **Cad**: Dimensionless  (exposed as **Cad**) +: **hs**: Dimensionless  (exposed as **hs**) +: **ns**: Dimensionless  (exposed as **ns**) +: **sd**: Dimensionless  (exposed as **sd**) +: **cd**: Dimensionless  (exposed as **cd**) +: **qd**: Dimensionless  (exposed as **qd**) +: **Si**: Dimensionless  (exposed as **Si**) +: **Wi**: Dimensionless  (exposed as **Wi**) +: **Sisat**: Dimensionless + + + + + + + + + +**On Start** +: **Vs** = eL +: **Vd** = eL +: **qd** = qd0 + + + + + +**Derived Variables** + : **v** = Vs (exposed as **v**) + : **ICad** = gCa*sd*sd*(Vd-eCa) (exposed as **ICad**) + : **alphams_Vs** = 0.32*(-46.9-Vs/MVOLT)/(exp((-46.9-Vs/MVOLT)/4.0)-1.0) + : **betams_Vs** = 0.28*(Vs/MVOLT+19.9)/(exp((Vs/MVOLT+19.9)/5.0)-1.0) + : **Minfs_Vs** = alphams_Vs/(alphams_Vs+betams_Vs) + : **alphans_Vs** = 0.016*(-24.9-Vs/MVOLT)/(exp((-24.9-Vs/MVOLT)/5.0)-1.0) + : **betans_Vs** = 0.25*exp(-1.0-0.025*Vs/MVOLT) + : **alphahs_Vs** = 0.128*exp((-43.0-Vs/MVOLT)/18.0) + : **betahs_Vs** = 4.0/(1.0+exp((-20.0-Vs/MVOLT)/5.0)) + : **alphasd_Vd** = 1.6/(1.0+exp(-0.072*(Vd/MVOLT-5.0))) + : **betasd_Vd** = 0.02*(Vd/MVOLT+8.9)/(exp((Vd/MVOLT+8.9)/5.0)-1.0) + : **Iampa** = gAmpa*Wi*(Vd-Vsyn) + : **Inmda** = gNmda*Sisat*(Vd-Vsyn)/(1.0+0.28*exp(-0.062*(Vd/MVOLT-60.0))) + : **Isyn** = Iampa+Inmda + + + + +**Conditional Derived Variables** + +: IF 0.00002*Cad > 0.01 THEN +:   **alphaqd** = 0.01 +: OTHERWISE +:   **alphaqd** = 0.00002\*Cad +: IF Cad/250 > 1 THEN +:   **chid** = 1 +: OTHERWISE +:   **chid** = Cad/250 +: IF Vd < -10*MVOLT THEN +:   **alphacd_Vd** = exp((Vd/MVOLT+50.0)/11-(Vd/MVOLT+53.5)/27)/18.975 +: OTHERWISE +:   **alphacd_Vd** = 2.0\*exp((-53.5-Vd/MVOLT)/27.0) +: IF Vd < -10*MVOLT THEN +:   **betacd_Vd** = (2.0\*exp((-53.5-Vd/MVOLT)/27.0)-alphacd_Vd) +: OTHERWISE +:   **betacd_Vd** = 0 +: IF Si > Smax THEN +:   **Sisat** = Smax +: OTHERWISE +:   **Sisat** = Si + + +**Time Derivatives** + : d **Vs** /dt = (-gLs*(Vs-eL)-gNa*(Minfs_Vs^2)*hs*(Vs-eNa)-gKdr*ns*(Vs-eK)+(gc/pp)*(Vd-Vs)+iSoma/pp) / cm + : d **Vd** /dt = (iDend/(1.0-pp)-Isyn/(1.0-pp)-gLd*(Vd-eL)-ICad-gKahp*qd*(Vd-eK)-gKC*cd*chid*(Vd-eK)+(gc*(Vs-Vd))/(1.0-pp)) / cm + : d **Cad** /dt = (-0.13*ICad/UAMP_PER_CM2-0.075*Cad) / MSEC + : d **hs** /dt = (alphahs_Vs-(alphahs_Vs+betahs_Vs)*hs) / MSEC + : d **ns** /dt = (alphans_Vs-(alphans_Vs+betans_Vs)*ns) / MSEC + : d **sd** /dt = (alphasd_Vd-(alphasd_Vd+betasd_Vd)*sd) / MSEC + : d **cd** /dt = (alphacd_Vd-(alphacd_Vd+betacd_Vd)*cd) / MSEC + : d **qd** /dt = (alphaqd-(alphaqd+betaqd)*qd) / MSEC + : d **Si** /dt = -Si/150.0 + : d **Wi** /dt = -Wi/2.0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import PinskyRinzelCA3Cell + +variable = PinskyRinzelCA3Cell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + i_soma: 'a Nml2Quantity_currentDensity (required)' = None, + i_dend: 'a Nml2Quantity_currentDensity (required)' = None, + gc: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_ls: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_ld: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_na: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_kdr: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_ca: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_kahp: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_kc: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_nmda: 'a Nml2Quantity_conductanceDensity (required)' = None, + g_ampa: 'a Nml2Quantity_conductanceDensity (required)' = None, + e_na: 'a Nml2Quantity_voltage (required)' = None, + e_ca: 'a Nml2Quantity_voltage (required)' = None, + e_k: 'a Nml2Quantity_voltage (required)' = None, + e_l: 'a Nml2Quantity_voltage (required)' = None, + qd0: 'a Nml2Quantity_none (required)' = None, + pp: 'a Nml2Quantity_none (required)' = None, + alphac: 'a Nml2Quantity_none (required)' = None, + betac: 'a Nml2Quantity_none (required)' = None, + cm: 'a Nml2Quantity_specificCapacitance (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:hindmarshrose1984cell)= + +## hindmarshRose1984Cell + + + + +extends *{ref}`schema:basecellmembpotcap`* + + + +The Hindmarsh Rose model is a simplified point cell model which captures complex firing patterns of single neurons, such as periodic and chaotic bursting. It has a fast spiking subsystem, which is a generalization of the FitzHugh-Nagumo system, coupled to a slower subsystem which allows the model to fire bursts. The dynamical variables x, y, z correspond to the membrane potential, a recovery variable, and a slower adaptation current, respectively. See Hindmarsh J. L., and Rose R. M. ( 1984 ) A model of neuronal bursting using three coupled first order differential equations. Proc. R. Soc. London, Ser. B 221:87–102. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**C**$ Total capacitance of the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:capacitance` +**a**$ cubic term in x nullcline $Dimensionless +**b**$ quadratic term in x nullcline $Dimensionless +**c**$ constant term in y nullcline $Dimensionless +**d**$ quadratic term in y nullcline $Dimensionless +**r**$ timescale separation between slow and fast subsystem (r greater than 0; r much less than 1) $Dimensionless +**s**$ related to adaptation $Dimensionless +**v_scaling**$ scaling of x for physiological membrane potential ${ref}`schema:dimensions:voltage` +**x0**$ $Dimensionless +**x1**$ related to the system's resting potential $Dimensionless +**y0**$ $Dimensionless +**z0**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MSEC** = 1ms$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**chi**$ $Dimensionless +**iMemb**$ Total current crossing the cell membrane *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**iSyn**$ Total current due to synaptic inputs *(from {ref}`schema:basecellmembpotcap`)* ${ref}`schema:dimensions:current` +**phi**$ $Dimensionless +**rho**$ $Dimensionless +**spiking**$ $Dimensionless +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` +**x**$ $Dimensionless +**y**$ $Dimensionless +**z**$ $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **y**: Dimensionless  (exposed as **y**) +: **z**: Dimensionless  (exposed as **z**) +: **spiking**: Dimensionless  (exposed as **spiking**) + + + + + + + + + +**On Start** +: **v** = x0 * v_scaling +: **y** = y0 +: **z** = z0 + + + +**On Conditions** + +: IF v > 0 AND spiking < 0.5 THEN +:    **spiking** = 1 +:    EVENT OUT on port: **spike** + +: IF v < 0 THEN +:    **spiking** = 0 + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **x** = v / v_scaling (exposed as **x**) + : **phi** = y - a * x^3 + b * x^2 (exposed as **phi**) + : **chi** = c - d * x^2 - y (exposed as **chi**) + : **rho** = s * ( x - x1 ) - z (exposed as **rho**) + : **iMemb** = (C * (v_scaling * (phi - z) / MSEC)) + iSyn (exposed as **iMemb**) + + + + + + +**Time Derivatives** + : d **v** /dt = iMemb/C + : d **y** /dt = chi / MSEC + : d **z** /dt = r * rho / MSEC + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import HindmarshRose1984Cell + +variable = HindmarshRose1984Cell( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + C: 'a Nml2Quantity_capacitance (required)' = None, + a: 'a Nml2Quantity_none (required)' = None, + b: 'a Nml2Quantity_none (required)' = None, + c: 'a Nml2Quantity_none (required)' = None, + d: 'a Nml2Quantity_none (required)' = None, + s: 'a Nml2Quantity_none (required)' = None, + x1: 'a Nml2Quantity_none (required)' = None, + r: 'a Nml2Quantity_none (required)' = None, + x0: 'a Nml2Quantity_none (required)' = None, + y0: 'a Nml2Quantity_none (required)' = None, + z0: 'a Nml2Quantity_none (required)' = None, + v_scaling: 'a Nml2Quantity_voltage (required)' = None, +) +``` +```` +````` diff --git a/_sources/Userdocs/Schemas/Channels.md b/_sources/Userdocs/Schemas/Channels.md new file mode 100644 index 00000000..7377ae8a --- /dev/null +++ b/_sources/Userdocs/Schemas/Channels.md @@ -0,0 +1,3632 @@ + +(schema:channels_)= +# Channels + +**Defines voltage ( and concentration ) gated ion channel models. Ion channels will generally extend {ref}`schema:baseionchannel`. The most commonly used voltage dependent gate will extend {ref}`schema:basegate`.** + +--- + + +Original ComponentType definitions: [Channels.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//Channels.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:basevoltagedeprate)= + +## *baseVoltageDepRate* + + + + +Base ComponentType for voltage dependent rate. Produces a time varying rate **r** which depends on **v.**. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**r**$ ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basevoltageconcdeprate)= + +## *baseVoltageConcDepRate* + + + + +extends *{ref}`schema:basevoltagedeprate`* + + + +Base ComponentType for voltage and concentration dependent rate. Produces a time varying rate **r** which depends on **v** and **caConc.**. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**r**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**v**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basehhrate)= + +## *baseHHRate* + + + + +extends *{ref}`schema:basevoltagedeprate`* + + + +Base ComponentType for rate which follow one of the typical forms for rate equations in the standard HH formalism, using the parameters **rate,** **midpoint** and **scale**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ ${ref}`schema:dimensions:voltage` +**rate**$ ${ref}`schema:dimensions:per_time` +**scale**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**r**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:hhexprate)= + +## HHExpRate + + + + +extends *{ref}`schema:basehhrate`* + + + +Exponential form for rate equation ( Q: Should these be renamed hhExpRate, etc? ). + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:voltage` +**rate**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:per_time` +**scale**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**r**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **r** = rate * exp((v - midpoint)/scale) (exposed as **r**) + + + + + + +```` +````` + +(schema:hhsigmoidrate)= + +## HHSigmoidRate + + + + +extends *{ref}`schema:basehhrate`* + + + +Sigmoidal form for rate equation. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:voltage` +**rate**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:per_time` +**scale**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**r**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **r** = rate / (1 + exp(0 - (v - midpoint)/scale)) (exposed as **r**) + + + + + + +```` +````` + +(schema:hhexplinearrate)= + +## HHExpLinearRate + + + + +extends *{ref}`schema:basehhrate`* + + + +Exponential linear form for rate equation. Linear for large positive **v,** exponentially decays for large negative **v.**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:voltage` +**rate**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:per_time` +**scale**$ *(from {ref}`schema:basehhrate`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**r**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedeprate`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **x** = (v - midpoint) / scale + + + + +**Conditional Derived Variables** + +: IF x != 0 THEN +:   **r** = rate \* x / (1 - exp(0 - x))  (exposed as **r**) +: IF x = 0 THEN +:   **r** = rate  (exposed as **r**) + + +```` +````` + +(schema:basevoltagedepvariable)= + +## *baseVoltageDepVariable* + + + + +Base ComponentType for voltage dependent variable **x,** which depends on **v.** Can be used for inf/steady state of rate variable. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basevoltageconcdepvariable)= + +## *baseVoltageConcDepVariable* + + + + +extends *{ref}`schema:basevoltagedepvariable`* + + + +Base ComponentType for voltage and calcium concentration dependent variable **x,** which depends on **v** and **caConc.**. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ *(from {ref}`schema:basevoltagedepvariable`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**v**$ *(from {ref}`schema:basevoltagedepvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basehhvariable)= + +## *baseHHVariable* + + + + +extends *{ref}`schema:basevoltagedepvariable`* + + + +Base ComponentType for voltage dependent dimensionless variable which follow one of the typical forms for variable equations in the standard HH formalism, using the parameters **rate,** **midpoint,** **scale**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ ${ref}`schema:dimensions:voltage` +**rate**$ $Dimensionless +**scale**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ *(from {ref}`schema:basevoltagedepvariable`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedepvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:hhexpvariable)= + +## HHExpVariable + + + + +extends *{ref}`schema:basehhvariable`* + + + +Exponential form for variable equation. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ *(from {ref}`schema:basehhvariable`)* ${ref}`schema:dimensions:voltage` +**rate**$ *(from {ref}`schema:basehhvariable`)* $Dimensionless +**scale**$ *(from {ref}`schema:basehhvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ *(from {ref}`schema:basevoltagedepvariable`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedepvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **x** = rate * exp((v - midpoint)/scale) (exposed as **x**) + + + + + + +```` +````` + +(schema:hhsigmoidvariable)= + +## HHSigmoidVariable + + + + +extends *{ref}`schema:basehhvariable`* + + + +Sigmoidal form for variable equation. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ *(from {ref}`schema:basehhvariable`)* ${ref}`schema:dimensions:voltage` +**rate**$ *(from {ref}`schema:basehhvariable`)* $Dimensionless +**scale**$ *(from {ref}`schema:basehhvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ *(from {ref}`schema:basevoltagedepvariable`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedepvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **x** = rate / (1 + exp(0 - (v - midpoint)/scale)) (exposed as **x**) + + + + + + +```` +````` + +(schema:hhexplinearvariable)= + +## HHExpLinearVariable + + + + +extends *{ref}`schema:basehhvariable`* + + + +Exponential linear form for variable equation. Linear for large positive **v,** exponentially decays for large negative **v.**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**midpoint**$ *(from {ref}`schema:basehhvariable`)* ${ref}`schema:dimensions:voltage` +**rate**$ *(from {ref}`schema:basehhvariable`)* $Dimensionless +**scale**$ *(from {ref}`schema:basehhvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ *(from {ref}`schema:basevoltagedepvariable`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedepvariable`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **a** = (v - midpoint) / scale + : **x** = rate * a / (1 - exp(0 - a)) (exposed as **x**) + + + + + + +```` +````` + +(schema:basevoltagedeptime)= + +## *baseVoltageDepTime* + + + + +Base ComponentType for voltage dependent ComponentType producing value **t** with dimension time ( e.g. for time course of rate variable ). Note: time course would not normally be fit to exp/sigmoid etc. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**t**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basevoltageconcdeptime)= + +## *baseVoltageConcDepTime* + + + + +extends *{ref}`schema:basevoltagedeptime`* + + + +Base type for voltage and calcium concentration dependent ComponentType producing value **t** with dimension time ( e.g. for time course of rate variable ). + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**t**$ *(from {ref}`schema:basevoltagedeptime`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**v**$ *(from {ref}`schema:basevoltagedeptime`)* ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:fixedtimecourse)= + +## fixedTimeCourse + + + + +extends *{ref}`schema:basevoltagedeptime`* + + + +Time course of a fixed magnitude **tau** which can be used for the time course in {ref}`schema:gatehhtauinf`, {ref}`schema:gatehhratestau` or {ref}`schema:gatehhratestauinf`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**t**$ *(from {ref}`schema:basevoltagedeptime`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:basevoltagedeptime`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **t** = tau (exposed as **t**) + + + + + + +```` +````` + +(schema:baseq10settings)= + +## *baseQ10Settings* + + + + +Base ComponentType for a scaling to apply to gating variable time course, usually temperature dependent. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**q10**$ $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**temperature**$ ${ref}`schema:dimensions:temperature` + +``` +```` +````` + +(schema:q10fixed)= + +## q10Fixed + + + + +extends *{ref}`schema:baseq10settings`* + + + +A fixed value, **fixedQ10,** for the scaling of the time course of the gating variable. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fixedQ10**$ $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**q10**$ *(from {ref}`schema:baseq10settings`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**temperature**$ *(from {ref}`schema:baseq10settings`)* ${ref}`schema:dimensions:temperature` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **q10** = fixedQ10 (exposed as **q10**) + + + + + + +```` +````` + +(schema:q10exptemp)= + +## q10ExpTemp + + + + +extends *{ref}`schema:baseq10settings`* + + + +A value for the Q10 scaling which varies as a standard function of the difference between the current temperature, **temperature,** and the temperature at which the gating variable equations were determined, **experimentalTemp**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**experimentalTemp**$ ${ref}`schema:dimensions:temperature` +**q10Factor**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**TENDEGREES** = 10K$ $ {ref}`schema:dimensions:temperature` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**q10**$ *(from {ref}`schema:baseq10settings`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**temperature**$ *(from {ref}`schema:baseq10settings`)* ${ref}`schema:dimensions:temperature` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **q10** = q10Factor^((temperature - experimentalTemp)/TENDEGREES) (exposed as **q10**) + + + + + + +```` +````` + +(schema:baseconductancescaling)= + +## *baseConductanceScaling* + + + + +Base ComponentType for a scaling to apply to a gate's conductance, e.g. temperature dependent scaling. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**factor**$ $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**temperature**$ ${ref}`schema:dimensions:temperature` + +``` +```` +````` + +(schema:q10conductancescaling)= + +## q10ConductanceScaling + + + + +extends *{ref}`schema:baseconductancescaling`* + + + +A value for the conductance scaling which varies as a standard function of the difference between the current temperature, **temperature,** and the temperature at which the conductance was originally determined, **experimentalTemp**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**experimentalTemp**$ ${ref}`schema:dimensions:temperature` +**q10Factor**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**TENDEGREES** = 10K$ $ {ref}`schema:dimensions:temperature` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**factor**$ *(from {ref}`schema:baseconductancescaling`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**temperature**$ *(from {ref}`schema:baseconductancescaling`)* ${ref}`schema:dimensions:temperature` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **factor** = q10Factor^((temperature - experimentalTemp)/TENDEGREES) (exposed as **factor**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Q10ConductanceScaling + +variable = Q10ConductanceScaling( + q10_factor: 'a Nml2Quantity_none (required)' = None, + experimental_temp: 'a Nml2Quantity_temperature (required)' = None, +) +``` +```` +````` + +(schema:baseconductancescalingcadependent)= + +## *baseConductanceScalingCaDependent* + + + + +extends *{ref}`schema:baseconductancescaling`* + + + +Base ComponentType for a scaling to apply to a gate's conductance which depends on Ca concentration. Usually a generic expression of **caConc** ( so no standard, non-base form here ). + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**factor**$ *(from {ref}`schema:baseconductancescaling`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**caConc**$ ${ref}`schema:dimensions:concentration` +**temperature**$ *(from {ref}`schema:baseconductancescaling`)* ${ref}`schema:dimensions:temperature` + +``` +```` +````` + +(schema:basegate)= + +## *baseGate* + + + + +Base ComponentType for a voltage and/or concentration dependent gate. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**notes**$ $ {ref}`schema:notes` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fcond**$ $Dimensionless +**q**$ $Dimensionless + +``` +```` +````` + +(schema:gate)= + +## gate + + + + +extends *{ref}`schema:basegate`* + + + +Conveniently named baseGate. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` +````` + +(schema:gatehhrates)= + +## gateHHrates + + + + +extends {ref}`schema:gate` + + + +Gate which follows the general Hodgkin Huxley formalism. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**forwardRate**$ $ {ref}`schema:basevoltagedeprate` +**reverseRate**$ $ {ref}`schema:basevoltagedeprate` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**q10Settings**$ $ {ref}`schema:baseq10settings` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**alpha**$ ${ref}`schema:dimensions:per_time` +**beta**$ ${ref}`schema:dimensions:per_time` +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**inf**$ $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **q**: Dimensionless  (exposed as **q**) + + + + + + + + + +**On Start** +: **q** = inf + + + + + +**Derived Variables** + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + : **alpha** = forwardRate->r (exposed as **alpha**) + : **beta** = reverseRate->r (exposed as **beta**) + : **fcond** = q^instances (exposed as **fcond**) + : **inf** = alpha/(alpha+beta) (exposed as **inf**) + : **tau** = 1/((alpha+beta) * rateScale) (exposed as **tau**) + + + + + + +**Time Derivatives** + : d **q** /dt = (inf - q) / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + + +````{tab-item} Usage: XML +```{code-block} xml + + + + +``` +```{code-block} xml + + + + +``` +```{code-block} xml + + + + +``` +```` +````` + +(schema:gatehhtauinf)= + +## gateHHtauInf + + + + +extends {ref}`schema:gate` + + + +Gate which follows the general Hodgkin Huxley formalism. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**timeCourse**$ $ {ref}`schema:basevoltagedeptime` +**steadyState**$ $ {ref}`schema:basevoltagedepvariable` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**q10Settings**$ $ {ref}`schema:baseq10settings` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**inf**$ $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **q**: Dimensionless  (exposed as **q**) + + + + + + + + + +**On Start** +: **q** = inf + + + + + +**Derived Variables** + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + : **fcond** = q^instances (exposed as **fcond**) + : **inf** = steadyState->x (exposed as **inf**) + : **tauUnscaled** = timeCourse->t + : **tau** = tauUnscaled / rateScale (exposed as **tau**) + + + + + + +**Time Derivatives** + : d **q** /dt = (inf - q) / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` +````` + +(schema:gatehhinstantaneous)= + +## gateHHInstantaneous + + + + +extends {ref}`schema:gate` + + + +Gate which follows the general Hodgkin Huxley formalism but is instantaneous, so tau = 0 and gate follows exactly inf value. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SEC** = 1 s$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**steadyState**$ $ {ref}`schema:basevoltagedepvariable` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**inf**$ $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **inf** = steadyState->x (exposed as **inf**) + : **tau** = 0 * SEC (exposed as **tau**) + : **q** = inf (exposed as **q**) + : **fcond** = q^instances (exposed as **fcond**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import GateHHInstantaneous + +variable = GateHHInstantaneous( + id: 'a NmlId (required)' = None, + instances: 'a PositiveInteger (required)' = None, + notes: 'a string (optional)' = None, + steady_state: 'a HHVariable (required)' = None, +) +``` +```` +````` + +(schema:gatehhratestau)= + +## gateHHratesTau + + + + +extends {ref}`schema:gate` + + + +Gate which follows the general Hodgkin Huxley formalism. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**forwardRate**$ $ {ref}`schema:basevoltagedeprate` +**reverseRate**$ $ {ref}`schema:basevoltagedeprate` +**timeCourse**$ $ {ref}`schema:basevoltagedeptime` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**q10Settings**$ $ {ref}`schema:baseq10settings` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**alpha**$ ${ref}`schema:dimensions:per_time` +**beta**$ ${ref}`schema:dimensions:per_time` +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**inf**$ $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **q**: Dimensionless  (exposed as **q**) + + + + + + + + + +**On Start** +: **q** = inf + + + + + +**Derived Variables** + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + : **alpha** = forwardRate->r (exposed as **alpha**) + : **beta** = reverseRate->r (exposed as **beta**) + : **fcond** = q^instances (exposed as **fcond**) + : **inf** = alpha/(alpha+beta) (exposed as **inf**) + : **tauUnscaled** = timeCourse->t + : **tau** = tauUnscaled / rateScale (exposed as **tau**) + + + + + + +**Time Derivatives** + : d **q** /dt = (inf - q) / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` +````` + +(schema:gatehhratesinf)= + +## gateHHratesInf + + + + +extends {ref}`schema:gate` + + + +Gate which follows the general Hodgkin Huxley formalism. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**forwardRate**$ $ {ref}`schema:basevoltagedeprate` +**reverseRate**$ $ {ref}`schema:basevoltagedeprate` +**steadyState**$ $ {ref}`schema:basevoltagedepvariable` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**q10Settings**$ $ {ref}`schema:baseq10settings` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**alpha**$ ${ref}`schema:dimensions:per_time` +**beta**$ ${ref}`schema:dimensions:per_time` +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**inf**$ $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **q**: Dimensionless  (exposed as **q**) + + + + + + + + + +**On Start** +: **q** = inf + + + + + +**Derived Variables** + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + : **alpha** = forwardRate->r (exposed as **alpha**) + : **beta** = reverseRate->r (exposed as **beta**) + : **fcond** = q^instances (exposed as **fcond**) + : **inf** = steadyState->x (exposed as **inf**) + : **tau** = 1/((alpha+beta) * rateScale) (exposed as **tau**) + + + + + + +**Time Derivatives** + : d **q** /dt = (inf - q) / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + +``` +```` +````` + +(schema:gatehhratestauinf)= + +## gateHHratesTauInf + + + + +extends {ref}`schema:gate` + + + +Gate which follows the general Hodgkin Huxley formalism. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**forwardRate**$ $ {ref}`schema:basevoltagedeprate` +**reverseRate**$ $ {ref}`schema:basevoltagedeprate` +**timeCourse**$ $ {ref}`schema:basevoltagedeptime` +**steadyState**$ $ {ref}`schema:basevoltagedepvariable` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**q10Settings**$ $ {ref}`schema:baseq10settings` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**alpha**$ ${ref}`schema:dimensions:per_time` +**beta**$ ${ref}`schema:dimensions:per_time` +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**inf**$ $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **q**: Dimensionless  (exposed as **q**) + + + + + + + + + +**On Start** +: **q** = inf + + + + + +**Derived Variables** + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + : **alpha** = forwardRate->r (exposed as **alpha**) + : **beta** = reverseRate->r (exposed as **beta**) + : **inf** = steadyState->x (exposed as **inf**) + : **tauUnscaled** = timeCourse->t + : **tau** = tauUnscaled / rateScale (exposed as **tau**) + : **fcond** = q^instances (exposed as **fcond**) + + + + + + +**Time Derivatives** + : d **q** /dt = (inf - q) / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + +``` +```` +````` + +(schema:gatefractional)= + +## gateFractional + + + + +extends {ref}`schema:gate` + + + +Gate composed of subgates contributing with fractional conductance. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**q10Settings**$ $ {ref}`schema:baseq10settings` +**subGate**$ $ {ref}`schema:subgate` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **q** = subGate[*]->qfrac(reduce method: add) (exposed as **q**) + : **fcond** = q^instances (exposed as **fcond**) + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import GateFractional + +variable = GateFractional( + id: 'a NmlId (required)' = None, + instances: 'a PositiveInteger (required)' = None, + notes: 'a string (optional)' = None, + q10_settings: 'a Q10Settings (optional)' = None, + sub_gates: 'list of GateFractionalSubgate(s) (required)' = None, +) +``` +```` +````` + +(schema:subgate)= + +## subGate + + + + +Gate composed of subgates contributing with fractional conductance. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fractionalConductance**$ $Dimensionless + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**notes**$ $ {ref}`schema:notes` +**timeCourse**$ $ {ref}`schema:basevoltagedeptime` +**steadyState**$ $ {ref}`schema:basevoltagedepvariable` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**inf**$ $Dimensionless +**q**$ $Dimensionless +**qfrac**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**rateScale**$ $Dimensionless + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **q**: Dimensionless  (exposed as **q**) + + + + + + + + + +**On Start** +: **q** = inf + + + + + +**Derived Variables** + : **inf** = steadyState->x (exposed as **inf**) + : **tauUnscaled** = timeCourse->t + : **tau** = tauUnscaled / rateScale (exposed as **tau**) + : **qfrac** = q * fractionalConductance (exposed as **qfrac**) + + + + + + +**Time Derivatives** + : d **q** /dt = (inf - q) / tau + + +```` +````` + +(schema:baseionchannel)= + +## *baseIonChannel* + + + + +Base for all ion channel ComponentTypes. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**neuroLexId**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**notes**$ $ {ref}`schema:notes` +**annotation**$ $ {ref}`schema:annotation` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fopen**$ $Dimensionless +**g**$ ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:ionchannelpassive)= + +## ionChannelPassive + + + + +extends {ref}`schema:ionchannel` + + + +Simple passive ion channel where the constant conductance through the channel is equal to **conductance**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**species**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fopen**$ *(from {ref}`schema:baseionchannel`)* $Dimensionless +**g**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **fopen** = 1 (exposed as **fopen**) + : **g** = conductance (exposed as **g**) + + + + + + +```` +````` + +(schema:ionchannelhh)= + +## ionChannelHH + + + + +extends *{ref}`schema:baseionchannel`* + + + +Note {ref}`schema:ionchannel` and {ref}`schema:ionchannelhh` are currently functionally identical. This is needed since many existing examples use ionChannel, some use ionChannelHH. NeuroML v2beta4 should remove one of these, probably ionChannelHH. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**species**$ + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**conductanceScaling**$ $ {ref}`schema:baseconductancescaling` +**gates**$ $ {ref}`schema:gate` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fopen**$ *(from {ref}`schema:baseionchannel`)* $Dimensionless +**g**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **conductanceScale** = conductanceScaling[*]->factor(reduce method: multiply) + : **fopen0** = gates[*]->fcond(reduce method: multiply) + : **fopen** = conductanceScale * fopen0 (exposed as **fopen**) + : **g** = conductance * fopen (exposed as **g**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IonChannelHH + +variable = IonChannelHH( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + q10_conductance_scalings: 'list of Q10ConductanceScaling(s) (optional)' = None, + species: 'a NmlId (optional)' = None, + type: 'a channelTypes (optional)' = None, + conductance: 'a Nml2Quantity_conductance (optional)' = None, + gates: 'list of GateHHUndetermined(s) (optional)' = None, + gate_hh_rates: 'list of GateHHRates(s) (optional)' = None, + gate_h_hrates_taus: 'list of GateHHRatesTau(s) (optional)' = None, + gate_hh_tau_infs: 'list of GateHHTauInf(s) (optional)' = None, + gate_h_hrates_infs: 'list of GateHHRatesInf(s) (optional)' = None, + gate_h_hrates_tau_infs: 'list of GateHHRatesTauInf(s) (optional)' = None, + gate_hh_instantaneouses: 'list of GateHHInstantaneous(s) (optional)' = None, + gate_fractionals: 'list of GateFractional(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + + + +``` +```{code-block} xml + + + + + + + + + + +``` +```` +````` + +(schema:ionchannel)= + +## ionChannel + + + + +extends {ref}`schema:ionchannelhh` + + + +Note {ref}`schema:ionchannel` and {ref}`schema:ionchannelhh` are currently functionally identical. This is needed since many existing examples use ionChannel, some use ionChannelHH. NeuroML v2beta4 should remove one of these, probably ionChannelHH. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fopen**$ *(from {ref}`schema:baseionchannel`)* $Dimensionless +**g**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **conductanceScale** = conductanceScaling[*]->factor(reduce method: multiply) + : **fopen0** = gates[*]->fcond(reduce method: multiply) + : **fopen** = conductanceScale * fopen0 (exposed as **fopen**) + : **g** = conductance * fopen (exposed as **g**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IonChannel + +variable = IonChannel( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + q10_conductance_scalings: 'list of Q10ConductanceScaling(s) (optional)' = None, + species: 'a NmlId (optional)' = None, + type: 'a channelTypes (optional)' = None, + conductance: 'a Nml2Quantity_conductance (optional)' = None, + gates: 'list of GateHHUndetermined(s) (optional)' = None, + gate_hh_rates: 'list of GateHHRates(s) (optional)' = None, + gate_h_hrates_taus: 'list of GateHHRatesTau(s) (optional)' = None, + gate_hh_tau_infs: 'list of GateHHTauInf(s) (optional)' = None, + gate_h_hrates_infs: 'list of GateHHRatesInf(s) (optional)' = None, + gate_h_hrates_tau_infs: 'list of GateHHRatesTauInf(s) (optional)' = None, + gate_hh_instantaneouses: 'list of GateHHInstantaneous(s) (optional)' = None, + gate_fractionals: 'list of GateFractional(s) (optional)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:ionchannelvshift)= + +## ionChannelVShift + + + + +extends {ref}`schema:ionchannel` + + + +Same as {ref}`schema:ionchannel`, but with a **vShift** parameter to change voltage activation of gates. The exact usage of **vShift** in expressions for rates is determined by the individual gates. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` +**vShift**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**species**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fopen**$ *(from {ref}`schema:baseionchannel`)* $Dimensionless +**g**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IonChannelVShift + +variable = IonChannelVShift( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + q10_conductance_scalings: 'list of Q10ConductanceScaling(s) (optional)' = None, + species: 'a NmlId (optional)' = None, + type: 'a channelTypes (optional)' = None, + conductance: 'a Nml2Quantity_conductance (optional)' = None, + gates: 'list of GateHHUndetermined(s) (optional)' = None, + gate_hh_rates: 'list of GateHHRates(s) (optional)' = None, + gate_h_hrates_taus: 'list of GateHHRatesTau(s) (optional)' = None, + gate_hh_tau_infs: 'list of GateHHTauInf(s) (optional)' = None, + gate_h_hrates_infs: 'list of GateHHRatesInf(s) (optional)' = None, + gate_h_hrates_tau_infs: 'list of GateHHRatesTauInf(s) (optional)' = None, + gate_hh_instantaneouses: 'list of GateHHInstantaneous(s) (optional)' = None, + gate_fractionals: 'list of GateFractional(s) (optional)' = None, + v_shift: 'a Nml2Quantity_voltage (required)' = None, +) +``` +```` +````` + +(schema:ksstate)= + +## KSState + + + + +One of the states in which a {ref}`schema:gateks` can be. The rates of transitions between these states are given by {ref}`schema:kstransition`s. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**relativeConductance**$ $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**occupancy**$ $Dimensionless +**q**$ $Dimensionless + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **occupancy**: Dimensionless  (exposed as **occupancy**) + + + + + + + +**Derived Variables** + : **q** = relativeConductance * occupancy (exposed as **q**) + + + + + + +```` +````` + +(schema:closedstate)= + +## closedState + + + + +extends {ref}`schema:ksstate` + + + +A {ref}`schema:ksstate` with **relativeConductance** of 0. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**relativeConductance**$ *(from {ref}`schema:ksstate`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**occupancy**$ *(from {ref}`schema:ksstate`)* $Dimensionless +**q**$ *(from {ref}`schema:ksstate`)* $Dimensionless + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ClosedState + +variable = ClosedState( + id: 'a NmlId (required)' = None, +) +``` +```` +````` + +(schema:openstate)= + +## openState + + + + +extends {ref}`schema:ksstate` + + + +A {ref}`schema:ksstate` with **relativeConductance** of 1. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**relativeConductance**$ *(from {ref}`schema:ksstate`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**occupancy**$ *(from {ref}`schema:ksstate`)* $Dimensionless +**q**$ *(from {ref}`schema:ksstate`)* $Dimensionless + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import OpenState + +variable = OpenState( + id: 'a NmlId (required)' = None, +) +``` +```` +````` + +(schema:ionchannelks)= + +## ionChannelKS + + + + +extends *{ref}`schema:baseionchannel`* + + + +A kinetic scheme based ion channel with multiple {ref}`schema:gateks`s, each of which consists of multiple {ref}`schema:ksstate`s and {ref}`schema:kstransition`s giving the rates of transition between them. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**species**$ + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**conductanceScaling**$ $ {ref}`schema:baseconductancescaling` +**gates**$ $ {ref}`schema:gateks` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fopen**$ *(from {ref}`schema:baseionchannel`)* $Dimensionless +**g**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ *(from {ref}`schema:baseionchannel`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **fopen** = gates[*]->fcond(reduce method: multiply) (exposed as **fopen**) + : **g** = fopen * conductance (exposed as **g**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IonChannelKS + +variable = IonChannelKS( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + species: 'a NmlId (optional)' = None, + conductance: 'a Nml2Quantity_conductance (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gate_kses: 'list of GateKS(s) (optional)' = None, +) +``` +```` +````` + +(schema:kstransition)= + +## KSTransition + + + + +Specified the forward and reverse rates of transition between two {ref}`schema:ksstate`s in a {ref}`schema:gateks`. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**rf**$ ${ref}`schema:dimensions:per_time` +**rr**$ ${ref}`schema:dimensions:per_time` + +``` +```` +````` + +(schema:forwardtransition)= + +## forwardTransition + + + + +extends {ref}`schema:kstransition` + + + +A forward only {ref}`schema:kstransition` for a {ref}`schema:gateks` which specifies a **rate** ( type {ref}`schema:basehhrate` ) which follows one of the standard Hodgkin Huxley forms ( e.g. {ref}`schema:hhexprate`, {ref}`schema:hhsigmoidrate`, {ref}`schema:hhexplinearrate`. + + +`````{tab-set} +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SEC** = 1s$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rate**$ $ {ref}`schema:basehhrate` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**rf**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` +**rr**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **rf0** = rate->r + : **rf** = rf0 (exposed as **rf**) + : **rr** = 0/SEC (exposed as **rr**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ForwardTransition + +variable = ForwardTransition( + id: 'a NmlId (required)' = None, + from_: 'a NmlId (required)' = None, + to: 'a NmlId (required)' = None, + anytypeobjs_=None, +) +``` +```` +````` + +(schema:reversetransition)= + +## reverseTransition + + + + +extends {ref}`schema:kstransition` + + + +A reverse only {ref}`schema:kstransition` for a {ref}`schema:gateks` which specifies a **rate** ( type {ref}`schema:basehhrate` ) which follows one of the standard Hodgkin Huxley forms ( e.g. {ref}`schema:hhexprate`, {ref}`schema:hhsigmoidrate`, {ref}`schema:hhexplinearrate`. + + +`````{tab-set} +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SEC** = 1s$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rate**$ $ {ref}`schema:basehhrate` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**rf**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` +**rr**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **rr0** = rate->r + : **rr** = rr0 (exposed as **rr**) + : **rf** = 0/SEC (exposed as **rf**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ReverseTransition + +variable = ReverseTransition( + id: 'a NmlId (required)' = None, + from_: 'a NmlId (required)' = None, + to: 'a NmlId (required)' = None, + anytypeobjs_=None, +) +``` +```` +````` + +(schema:vhalftransition)= + +## vHalfTransition + + + + +extends {ref}`schema:kstransition` + + + +Transition which specifies both the forward and reverse rates of transition. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**gamma**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` +**tauMin**$ ${ref}`schema:dimensions:time` +**vHalf**$ ${ref}`schema:dimensions:voltage` +**z**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**kte** = 25.3mV$ $ {ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**rf**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` +**rr**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **rf0** = exp(z * gamma * (v - vHalf) / kte) / tau + : **rr0** = exp(-z * (1 - gamma) * (v - vHalf) / kte) / tau + : **rf** = 1 / (1/rf0 + tauMin) (exposed as **rf**) + : **rr** = 1 / (1/rr0 + tauMin) (exposed as **rr**) + + + + + + +```` +````` + +(schema:tauinftransition)= + +## tauInfTransition + + + + +extends {ref}`schema:kstransition` + + + +KS Transition specified in terms of time constant {ref}`schema:tau` and steady state {ref}`schema:inf`. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**timeCourse**$ $ {ref}`schema:basevoltagedeptime` +**steadyState**$ $ {ref}`schema:basevoltagedepvariable` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**rf**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` +**rr**$ *(from {ref}`schema:kstransition`)* ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **tau** = timeCourse->t + : **inf** = steadyState->x + : **rf** = inf/tau (exposed as **rf**) + : **rr** = (1-inf)/tau (exposed as **rr**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import TauInfTransition + +variable = TauInfTransition( + id: 'a NmlId (required)' = None, + from_: 'a NmlId (required)' = None, + to: 'a NmlId (required)' = None, + steady_state: 'a HHVariable (required)' = None, + time_course: 'a HHTime (required)' = None, +) +``` +```` +````` + +(schema:gateks)= + +## gateKS + + + + +extends *{ref}`schema:basegate`* + + + +A gate which consists of multiple {ref}`schema:ksstate`s and {ref}`schema:kstransition`s giving the rates of transition between them. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**instances**$ *(from {ref}`schema:basegate`)* $Dimensionless + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**states**$ $ {ref}`schema:ksstate` +**transitions**$ $ {ref}`schema:kstransition` +**q10Settings**$ $ {ref}`schema:baseq10settings` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**fcond**$ *(from {ref}`schema:basegate`)* $Dimensionless +**q**$ *(from {ref}`schema:basegate`)* $Dimensionless +**rateScale**$ $Dimensionless + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **rateScale** = q10Settings[*]->q10(reduce method: multiply) (exposed as **rateScale**) + : **q** = states[*]->q(reduce method: add) (exposed as **q**) + : **fcond** = q^instances (exposed as **fcond**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import GateKS + +variable = GateKS( + id: 'a NmlId (required)' = None, + instances: 'a PositiveInteger (required)' = None, + notes: 'a string (optional)' = None, + q10_settings: 'a Q10Settings (optional)' = None, + closed_states: 'list of ClosedState(s) (required)' = None, + open_states: 'list of OpenState(s) (required)' = None, + forward_transition: 'list of ForwardTransition(s) (required)' = None, + reverse_transition: 'list of ReverseTransition(s) (required)' = None, + tau_inf_transition: 'list of TauInfTransition(s) (required)' = None, +) +``` +```` +````` diff --git a/_sources/Userdocs/Schemas/Index.md b/_sources/Userdocs/Schemas/Index.md new file mode 100644 index 00000000..4ad887f2 --- /dev/null +++ b/_sources/Userdocs/Schemas/Index.md @@ -0,0 +1,785 @@ +# Index + + + +- {ref}`adExIaFCell ` + + +- {ref}`alphaCondSynapse ` + + +- {ref}`alphaCurrentSynapse ` + + +- {ref}`alphaCurrSynapse ` + + +- {ref}`alphaSynapse ` + + +- {ref}`annotation ` + + +- {ref}`area ` + + +- {ref}`baseBlockMechanism ` + + +- {ref}`baseBqbiol ` + + +- {ref}`baseCell ` + + +- {ref}`baseCellMembPot ` + + +- {ref}`baseCellMembPotCap ` + + +- {ref}`baseCellMembPotDL ` + + +- {ref}`baseChannelDensity ` + + +- {ref}`baseChannelDensityCond ` + + +- {ref}`baseChannelPopulation ` + + +- {ref}`baseConductanceBasedSynapse ` + + +- {ref}`baseConductanceBasedSynapseTwo ` + + +- {ref}`baseConductanceScaling ` + + +- {ref}`baseConductanceScalingCaDependent ` + + +- {ref}`baseCurrentBasedSynapse ` + + +- {ref}`baseGate ` + + +- {ref}`baseGradedSynapse ` + + +- {ref}`baseHHRate ` + + +- {ref}`baseHHVariable ` + + +- {ref}`baseIaf ` + + +- {ref}`baseIafCapCell ` + + +- {ref}`baseIonChannel ` + + +- {ref}`basePlasticityMechanism ` + + +- {ref}`basePointCurrent ` + + +- {ref}`basePointCurrentDL ` + + +- {ref}`basePopulation ` + + +- {ref}`basePyNNCell ` + + +- {ref}`basePyNNIaFCell ` + + +- {ref}`basePyNNIaFCondCell ` + + +- {ref}`basePynnSynapse ` + + +- {ref}`baseQ10Settings ` + + +- {ref}`baseSpikeSource ` + + +- {ref}`baseSpikingCell ` + + +- {ref}`baseStandalone ` + + +- {ref}`baseSynapse ` + + +- {ref}`baseSynapseDL ` + + +- {ref}`baseVoltageConcDepRate ` + + +- {ref}`baseVoltageConcDepTime ` + + +- {ref}`baseVoltageConcDepVariable ` + + +- {ref}`baseVoltageDepPointCurrent ` + + +- {ref}`baseVoltageDepPointCurrentDL ` + + +- {ref}`baseVoltageDepPointCurrentSpiking ` + + +- {ref}`baseVoltageDepRate ` + + +- {ref}`baseVoltageDepSynapse ` + + +- {ref}`baseVoltageDepTime ` + + +- {ref}`baseVoltageDepVariable ` + + +- {ref}`biophysicalProperties ` + + +- {ref}`biophysicalProperties2CaPools ` + + +- {ref}`blockingPlasticSynapse ` + + +- {ref}`bqbiol_encodes ` + + +- {ref}`bqbiol_hasPart ` + + +- {ref}`bqbiol_hasProperty ` + + +- {ref}`bqbiol_hasTaxon ` + + +- {ref}`bqbiol_hasVersion ` + + +- {ref}`bqbiol_is ` + + +- {ref}`bqbiol_isDescribedBy ` + + +- {ref}`bqbiol_isEncodedBy ` + + +- {ref}`bqbiol_isHomologTo ` + + +- {ref}`bqbiol_isPartOf ` + + +- {ref}`bqbiol_isPropertyOf ` + + +- {ref}`bqbiol_isVersionOf ` + + +- {ref}`bqbiol_occursIn ` + + +- {ref}`bqmodel_is ` + + +- {ref}`bqmodel_isDerivedFrom ` + + +- {ref}`bqmodel_isDescribedBy ` + + +- {ref}`capacitance ` + + +- {ref}`cell ` + + +- {ref}`cell2CaPools ` + + +- {ref}`channelDensity ` + + +- {ref}`channelDensityGHK ` + + +- {ref}`channelDensityGHK2 ` + + +- {ref}`channelDensityNernst ` + + +- {ref}`channelDensityNernstCa2 ` + + +- {ref}`channelDensityNonUniform ` + + +- {ref}`channelDensityNonUniformGHK ` + + +- {ref}`channelDensityNonUniformNernst ` + + +- {ref}`channelDensityVShift ` + + +- {ref}`channelPopulation ` + + +- {ref}`channelPopulationNernst ` + + +- {ref}`charge ` + + +- {ref}`charge_per_mole ` + + +- {ref}`closedState ` + + +- {ref}`compoundInput ` + + +- {ref}`compoundInputDL ` + + +- {ref}`concentration ` + + +- {ref}`concentrationModel ` + + +- {ref}`conductance ` + + +- {ref}`conductance_per_voltage ` + + +- {ref}`conductanceDensity ` + + +- {ref}`connection ` + + +- {ref}`connectionWD ` + + +- {ref}`continuousConnection ` + + +- {ref}`continuousConnectionInstance ` + + +- {ref}`continuousConnectionInstanceW ` + + +- {ref}`continuousProjection ` + + +- {ref}`current ` + + +- {ref}`currentDensity ` + + +- {ref}`decayingPoolConcentrationModel ` + + +- {ref}`Display ` + + +- {ref}`distal ` + + +- {ref}`distalDetails ` + + +- {ref}`doubleSynapse ` + + +- {ref}`EIF_cond_alpha_isfa_ista ` + + +- {ref}`EIF_cond_exp_isfa_ista ` + + +- {ref}`electricalConnection ` + + +- {ref}`electricalConnectionInstance ` + + +- {ref}`electricalConnectionInstanceW ` + + +- {ref}`electricalProjection ` + + +- {ref}`EventOutputFile ` + + +- {ref}`EventSelection ` + + +- {ref}`expCondSynapse ` + + +- {ref}`expCurrSynapse ` + + +- {ref}`explicitConnection ` + + +- {ref}`explicitInput ` + + +- {ref}`expOneSynapse ` + + +- {ref}`expThreeSynapse ` + + +- {ref}`expTwoSynapse ` + + +- {ref}`fitzHughNagumoCell ` + + +- {ref}`fixedFactorConcentrationModel ` + + +- {ref}`fixedFactorConcentrationModelTraub ` + + +- {ref}`fixedTimeCourse ` + + +- {ref}`forwardTransition ` + + +- {ref}`from ` + + +- {ref}`gapJunction ` + + +- {ref}`gate ` + + +- {ref}`gateFractional ` + + +- {ref}`gateHHInstantaneous ` + + +- {ref}`gateHHrates ` + + +- {ref}`gateHHratesInf ` + + +- {ref}`gateHHratesTau ` + + +- {ref}`gateHHratesTauInf ` + + +- {ref}`gateHHtauInf ` + + +- {ref}`gateKS ` + + +- {ref}`gradedSynapse ` + + +- {ref}`HH_cond_exp ` + + +- {ref}`HHExpLinearRate ` + + +- {ref}`HHExpLinearVariable ` + + +- {ref}`HHExpRate ` + + +- {ref}`HHExpVariable ` + + +- {ref}`HHSigmoidRate ` + + +- {ref}`HHSigmoidVariable ` + + +- {ref}`hindmarshRose1984Cell ` + + +- {ref}`iafCell ` + + +- {ref}`iafRefCell ` + + +- {ref}`iafTauCell ` + + +- {ref}`iafTauRefCell ` + + +- {ref}`idealGasConstantDims ` + + +- {ref}`IF_cond_alpha ` + + +- {ref}`IF_cond_exp ` + + +- {ref}`IF_curr_alpha ` + + +- {ref}`IF_curr_exp ` + + +- {ref}`include ` + + +- {ref}`inhomogeneousParameter ` + + +- {ref}`inhomogeneousValue ` + + +- {ref}`initMembPotential ` + + +- {ref}`input ` + + +- {ref}`inputList ` + + +- {ref}`inputW ` + + +- {ref}`instance ` + + +- {ref}`intracellularProperties ` + + +- {ref}`intracellularProperties2CaPools ` + + +- {ref}`ionChannel ` + + +- {ref}`ionChannelHH ` + + +- {ref}`ionChannelKS ` + + +- {ref}`ionChannelPassive ` + + +- {ref}`ionChannelVShift ` + + +- {ref}`izhikevich2007Cell ` + + +- {ref}`izhikevichCell ` + + +- {ref}`KSState ` + + +- {ref}`KSTransition ` + + +- {ref}`length ` + + +- {ref}`Line ` + + +- {ref}`linearGradedSynapse ` + + +- {ref}`location ` + + +- {ref}`member ` + + +- {ref}`membraneProperties ` + + +- {ref}`membraneProperties2CaPools ` + + +- {ref}`Meta ` + + +- {ref}`morphology ` + + +- {ref}`network ` + + +- {ref}`networkWithTemperature ` + + +- {ref}`notes ` + + +- {ref}`openState ` + + +- {ref}`OutputColumn ` + + +- {ref}`OutputFile ` + + +- {ref}`parent ` + + +- {ref}`path ` + + +- {ref}`per_time ` + + +- {ref}`per_voltage ` + + +- {ref}`permeability ` + + +- {ref}`pinskyRinzelCA3Cell ` + + +- {ref}`point3DWithDiam ` + + +- {ref}`pointCellCondBased ` + + +- {ref}`pointCellCondBasedCa ` + + +- {ref}`poissonFiringSynapse ` + + +- {ref}`population ` + + +- {ref}`populationList ` + + +- {ref}`projection ` + + +- {ref}`property ` + + +- {ref}`proximal ` + + +- {ref}`proximalDetails ` + + +- {ref}`pulseGenerator ` + + +- {ref}`pulseGeneratorDL ` + + +- {ref}`q10ConductanceScaling ` + + +- {ref}`q10ExpTemp ` + + +- {ref}`q10Fixed ` + + +- {ref}`rampGenerator ` + + +- {ref}`rampGeneratorDL ` + + +- {ref}`rdf_Bag ` + + +- {ref}`rdf_Description ` + + +- {ref}`rdf_li ` + + +- {ref}`rdf_RDF ` + + +- {ref}`rectangularExtent ` + + +- {ref}`region ` + + +- {ref}`resistance ` + + +- {ref}`resistivity ` + + +- {ref}`reverseTransition ` + + +- {ref}`rho_factor ` + + +- {ref}`segment ` + + +- {ref}`segmentGroup ` + + +- {ref}`silentSynapse ` + + +- {ref}`Simulation ` + + +- {ref}`sineGenerator ` + + +- {ref}`sineGeneratorDL ` + + +- {ref}`species ` + + +- {ref}`specificCapacitance ` + + +- {ref}`spike ` + + +- {ref}`spikeArray ` + + +- {ref}`spikeGenerator ` + + +- {ref}`spikeGeneratorPoisson ` + + +- {ref}`spikeGeneratorRandom ` + + +- {ref}`spikeGeneratorRefPoisson ` + + +- {ref}`SpikeSourcePoisson ` + + +- {ref}`spikeThresh ` + + +- {ref}`stdpSynapse ` + + +- {ref}`subGate ` + + +- {ref}`substance ` + + +- {ref}`subTree ` + + +- {ref}`synapticConnection ` + + +- {ref}`synapticConnectionWD ` + + +- {ref}`tauInfTransition ` + + +- {ref}`temperature ` + + +- {ref}`time ` + + +- {ref}`timedSynapticInput ` + + +- {ref}`to ` + + +- {ref}`transientPoissonFiringSynapse ` + + +- {ref}`tsodyksMarkramDepFacMechanism ` + + +- {ref}`tsodyksMarkramDepMechanism ` + + +- {ref}`variableParameter ` + + +- {ref}`vHalfTransition ` + + +- {ref}`voltage ` + + +- {ref}`voltageClamp ` + + +- {ref}`voltageClampTriple ` + + +- {ref}`voltageConcDepBlockMechanism ` + + +- {ref}`volume ` diff --git a/_sources/Userdocs/Schemas/Inputs.md b/_sources/Userdocs/Schemas/Inputs.md new file mode 100644 index 00000000..1ba3b48a --- /dev/null +++ b/_sources/Userdocs/Schemas/Inputs.md @@ -0,0 +1,3188 @@ + +(schema:inputs_)= +# Inputs + +**A number of ComponentTypes for providing spiking ( e.g. {ref}`schema:spikegeneratorpoisson`, {ref}`schema:spikearray` ) and current inputs ( e.g. {ref}`schema:pulsegenerator`, {ref}`schema:voltageclamp`, {ref}`schema:timedsynapticinput`, {ref}`schema:poissonfiringsynapse` ) to other ComponentTypes** + +--- + + +Original ComponentType definitions: [Inputs.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//Inputs.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:basepointcurrent)= + +## *basePointCurrent* + + + + +extends *{ref}`schema:basestandalone`* + + + +Base type for all ComponentTypes which produce a current **i** ( with dimension current ). + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType ${ref}`schema:dimensions:current` + +``` +```` +````` + +(schema:basevoltagedeppointcurrent)= + +## *baseVoltageDepPointCurrent* + + + + +extends *{ref}`schema:basepointcurrent`* + + + +Base type for all ComponentTypes which produce a current **i** ( with dimension current ) and require a voltage **v** exposed on the parent Component, which would often be the membrane potential of a Component extending {ref}`schema:basecellmembpot`. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed ${ref}`schema:dimensions:voltage` + +``` +```` +````` + +(schema:basevoltagedeppointcurrentspiking)= + +## *baseVoltageDepPointCurrentSpiking* + + + + +extends *{ref}`schema:basevoltagedeppointcurrent`* + + + +Base type for all ComponentTypes which produce a current **i,** require a membrane potential **v** exposed on the parent and emit spikes ( on a port **spike** ). The exposed variable **tsince** can be used for plotting the time since the Component has spiked last. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` +**tsince**$ Time since the last spike was emitted ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted$Direction: out + +``` +```` +````` + +(schema:basepointcurrentdl)= + +## *basePointCurrentDL* + + + + +Base type for all ComponentTypes which produce a dimensionless current **I.** There are many dimensionless equivalents of all the core current producing ComponentTypes such as {ref}`schema:pulsegenerator` / {ref}`schema:pulsegeneratordl`, {ref}`schema:sinegenerator` / {ref}`schema:sinegeneratordl` and {ref}`schema:rampgenerator` / {ref}`schema:rampgeneratordl`. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType $Dimensionless + +``` +```` +````` + +(schema:basevoltagedeppointcurrentdl)= + +## *baseVoltageDepPointCurrentDL* + + + + +extends *{ref}`schema:basepointcurrentdl`* + + + +Base type for all ComponentTypes which produce a dimensionless current **I** and require a dimensionless membrane potential **V** exposed on the parent Component. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrentdl`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**V**$ The current may vary with the dimensionless voltage exposed by the ComponentType on which this is placed $Dimensionless + +``` +```` +````` + +(schema:basespikesource)= + +## *baseSpikeSource* + + + + +Base for any ComponentType whose main purpose is to emit spikes ( on a port **spike** ). The exposed variable **tsince** can be used for plotting the time since the Component has spiked last. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tsince**$ Time since the last spike was emitted ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted$Direction: out + +``` +```` +````` + +(schema:spikegenerator)= + +## spikeGenerator + + + + +extends *{ref}`schema:basespikesource`* + + + +Simple generator of spikes at a regular interval set by **period**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**period**$ Time between spikes. The first spike will be emitted after this time. ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SMALL_TIME** = 1e-9ms$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tnext**$ When the next spike should ideally be emitted (dt permitting) ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnext**: {ref}`schema:dimensions:time`  (exposed as **tnext**) + + + + + + + + + +**On Start** +: **tsince** = 0 +: **tnext** = period + + + +**On Conditions** + +: IF tnext - t < SMALL_TIME THEN +:    **tsince** = 0 +:    **tnext** = tnext+period +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnext** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeGenerator + +variable = SpikeGenerator( + id: 'a NonNegativeInteger (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + period: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:spikegeneratorrandom)= + +## spikeGeneratorRandom + + + + +extends *{ref}`schema:basespikesource`* + + + +Generator of spikes with a random interspike interval of at least **minISI** and at most **maxISI**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**maxISI**$ Maximum interspike interval ${ref}`schema:dimensions:time` +**minISI**$ Minimum interspike interval ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MSEC** = 1ms$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**isi**$ The interval until the next spike ${ref}`schema:dimensions:time` +**tnext**$ When the next spike should ideally be emitted (dt permitting) ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnext**: {ref}`schema:dimensions:time`  (exposed as **tnext**) +: **isi**: {ref}`schema:dimensions:time`  (exposed as **isi**) + + + + + + + + + +**On Start** +: **tsince** = 0 +: **isi** = minISI + MSEC * random((maxISI - minISI) / MSEC) +: **tnext** = isi + + + +**On Conditions** + +: IF t > tnext THEN +:    **isi** = minISI + MSEC * random((maxISI - minISI) / MSEC) +:    **tsince** = 0 +:    **tnext** = tnext+isi +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnext** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeGeneratorRandom + +variable = SpikeGeneratorRandom( + id: 'a NonNegativeInteger (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + max_isi: 'a Nml2Quantity_time (required)' = None, + min_isi: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:spikegeneratorpoisson)= + +## spikeGeneratorPoisson + + + + +extends *{ref}`schema:basespikesource`* + + + +Generator of spikes whose ISI is distributed according to an exponential PDF with scale: 1 / **averageRate**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageRate**$ The average rate at which spikes are emitted ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SMALL_TIME** = 1e-9ms$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**isi**$ The interval until the next spike ${ref}`schema:dimensions:time` +**tnextIdeal**$ This is the ideal/perfect next spike time, based on a newly generated isi, but dt precision will mean that it's usually slightly later than this ${ref}`schema:dimensions:time` +**tnextUsed**$ This is the next spike time for practical purposes, ensuring that it's later than the current time ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnextIdeal**: {ref}`schema:dimensions:time`  (exposed as **tnextIdeal**) +: **tnextUsed**: {ref}`schema:dimensions:time`  (exposed as **tnextUsed**) +: **isi**: {ref}`schema:dimensions:time`  (exposed as **isi**) + + + + + + + + + +**On Start** +: **tsince** = 0 +: **isi** = -1 * log(random(1)) / averageRate +: **tnextIdeal** = isi +: **tnextUsed** = isi + + + +**On Conditions** + +: IF t > tnextUsed THEN +:    **tsince** = 0 +:    **isi** = -1 * log(random(1)) / averageRate +:    **tnextIdeal** = (tnextIdeal+isi) +:    **tnextUsed** = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t ) +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnextUsed** /dt = 0 + : d **tnextIdeal** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeGeneratorPoisson + +variable = SpikeGeneratorPoisson( + id: 'a NonNegativeInteger (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + average_rate: 'a Nml2Quantity_pertime (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:spikegeneratorrefpoisson)= + +## spikeGeneratorRefPoisson + + + + +extends {ref}`schema:spikegeneratorpoisson` + + + +Generator of spikes whose ISI distribution is the maximum entropy distribution over [ **minimumISI,** +infinity ) with mean: 1 / **averageRate**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageRate**$ The average rate at which spikes are emitted *(from {ref}`schema:spikegeneratorpoisson`)* ${ref}`schema:dimensions:per_time` +**minimumISI**$ The minimum interspike interval ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageIsi**$ The average interspike interval ${ref}`schema:dimensions:time` +``` +   **averageIsi** = 1 / averageRate + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**isi**$ The interval until the next spike *(from {ref}`schema:spikegeneratorpoisson`)* ${ref}`schema:dimensions:time` +**tnextIdeal**$ This is the ideal/perfect next spike time, based on a newly generated isi, but dt precision will mean that it's usually slightly later than this *(from {ref}`schema:spikegeneratorpoisson`)* ${ref}`schema:dimensions:time` +**tnextUsed**$ This is the next spike time for practical purposes, ensuring that it's later than the current time *(from {ref}`schema:spikegeneratorpoisson`)* ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnextIdeal**: {ref}`schema:dimensions:time`  (exposed as **tnextIdeal**) +: **tnextUsed**: {ref}`schema:dimensions:time`  (exposed as **tnextUsed**) +: **isi**: {ref}`schema:dimensions:time`  (exposed as **isi**) + + + + + + + + + +**On Start** +: **tsince** = 0 +: **isi** = minimumISI - (averageIsi-minimumISI) * log(random(1)) +: **tnextIdeal** = isi +: **tnextUsed** = isi + + + +**On Conditions** + +: IF t > tnextUsed THEN +:    **tsince** = 0 +:    **isi** = minimumISI - (averageIsi-minimumISI) * log(random(1)) +:    **tnextIdeal** = (tnextIdeal+isi) +:    **tnextUsed** = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t ) +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnextUsed** /dt = 0 + : d **tnextIdeal** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeGeneratorRefPoisson + +variable = SpikeGeneratorRefPoisson( + id: 'a NonNegativeInteger (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + average_rate: 'a Nml2Quantity_pertime (required)' = None, + minimum_isi: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:poissonfiringsynapse)= + +## poissonFiringSynapse + + + + +extends *{ref}`schema:basevoltagedeppointcurrentspiking`* + + + +Poisson spike generator firing at **averageRate,** which is connected to single **synapse** that is triggered every time a spike is generated, producing an input current. See also {ref}`schema:transientpoissonfiringsynapse`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageRate**$ The average rate at which spikes are emitted ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SMALL_TIME** = 1e-9ms$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageIsi**$ The average interspike interval ${ref}`schema:dimensions:time` +``` +   **averageIsi** = 1 / averageRate + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**spikeTarget**$ The target of the spikes, i.e. the synapse + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` +**isi**$ The interval until the next spike ${ref}`schema:dimensions:time` +**tnextIdeal**$ ${ref}`schema:dimensions:time` +**tnextUsed**$ ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basevoltagedeppointcurrentspiking`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in +**spike**$ Port on which spikes are emitted$Direction: out +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basevoltagedeppointcurrentspiking`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **this** AS **a** +: WITH **spikeTarget** AS **b** +: CHILD INSTANCE: **synapse** +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnextIdeal**: {ref}`schema:dimensions:time`  (exposed as **tnextIdeal**) +: **tnextUsed**: {ref}`schema:dimensions:time`  (exposed as **tnextUsed**) +: **isi**: {ref}`schema:dimensions:time`  (exposed as **isi**) + + + + + + + + + +**On Start** +: **tsince** = 0 +: **isi** = - averageIsi * log(random(1)) +: **tnextIdeal** = isi +: **tnextUsed** = isi + + + +**On Conditions** + +: IF t > tnextUsed THEN +:    **tsince** = 0 +:    **isi** = - averageIsi * log(1 - random(1)) +:    **tnextIdeal** = (tnextIdeal+isi) +:    **tnextUsed** = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t ) +:    EVENT OUT on port: **spike** + + + + + +**Derived Variables** + : **iSyn** = synapse->i + : **i** = weight * iSyn (exposed as **i**) + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnextUsed** /dt = 0 + : d **tnextIdeal** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import PoissonFiringSynapse + +variable = PoissonFiringSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + average_rate: 'a Nml2Quantity_pertime (required)' = None, + synapse: 'a string (required)' = None, + spike_target: 'a string (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:transientpoissonfiringsynapse)= + +## transientPoissonFiringSynapse + + + + +extends *{ref}`schema:basevoltagedeppointcurrentspiking`* + + + +Poisson spike generator firing at **averageRate** after a **delay** and for a **duration,** connected to single **synapse** that is triggered every time a spike is generated, providing an input current. Similar to ComponentType {ref}`schema:poissonfiringsynapse`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageRate**$ ${ref}`schema:dimensions:per_time` +**delay**$ ${ref}`schema:dimensions:time` +**duration**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**SMALL_TIME** = 1e-9ms$ $ {ref}`schema:dimensions:time` +**LONG_TIME** = 1e9hour$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**averageIsi**$ ${ref}`schema:dimensions:time` +``` +   **averageIsi** = 1 / averageRate + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**spikeTarget**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` +**isi**$ ${ref}`schema:dimensions:time` +**tnextIdeal**$ ${ref}`schema:dimensions:time` +**tnextUsed**$ ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basevoltagedeppointcurrentspiking`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in +**spike**$ Port on which spikes are emitted$Direction: out +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basevoltagedeppointcurrentspiking`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **this** AS **a** +: WITH **spikeTarget** AS **b** +: CHILD INSTANCE: **synapse** +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnextIdeal**: {ref}`schema:dimensions:time`  (exposed as **tnextIdeal**) +: **tnextUsed**: {ref}`schema:dimensions:time`  (exposed as **tnextUsed**) +: **isi**: {ref}`schema:dimensions:time`  (exposed as **isi**) + + + + + + + + + +**On Start** +: **tsince** = 0 +: **isi** = - averageIsi * log(1 - random(1)) +delay +: **tnextIdeal** = isi +: **tnextUsed** = isi + + + +**On Conditions** + +: IF t > tnextUsed THEN +:    **tsince** = 0 +:    **isi** = - averageIsi * log(1 - random(1)) +:    **tnextIdeal** = (tnextIdeal+isi) + H(((t+isi) - (delay+duration))/duration)*LONG_TIME +:    **tnextUsed** = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t ) +:    EVENT OUT on port: **spike** + + + + + +**Derived Variables** + : **iSyn** = synapse->i + : **i** = weight * iSyn (exposed as **i**) + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnextUsed** /dt = 0 + : d **tnextIdeal** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import TransientPoissonFiringSynapse + +variable = TransientPoissonFiringSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + average_rate: 'a Nml2Quantity_pertime (required)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + synapse: 'a string (required)' = None, + spike_target: 'a string (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:timedsynapticinput)= + +## timedSynapticInput + + + + +extends *{ref}`schema:basevoltagedeppointcurrentspiking`* + + + +Spike array connected to a single **synapse,** producing a current triggered by each {ref}`schema:spike` in the array. + + +`````{tab-set} +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**spikeTarget**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**spikes**$ $ {ref}`schema:spike` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basevoltagedeppointcurrentspiking`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ This will receive events from the children$Direction: in +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basevoltagedeppointcurrentspiking`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **this** AS **a** +: WITH **spikeTarget** AS **b** +: CHILD INSTANCE: **synapse** +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** +:    **tsince** = 0 +:    EVENT OUT on port: **spike** + + + + + +**Derived Variables** + : **iSyn** = synapse->i + : **i** = weight * iSyn (exposed as **i**) + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import TimedSynapticInput + +variable = TimedSynapticInput( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + synapse: 'a NmlId (required)' = None, + spike_target: 'a string (required)' = None, + spikes: 'list of Spike(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +```` +````` + +(schema:spikearray)= + +## spikeArray + + + + +extends *{ref}`schema:basespikesource`* + + + +Set of spike ComponentTypes, each emitting one spike at a certain time. Can be used to feed a predetermined spike train into a cell. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**spikes**$ $ {ref}`schema:spike` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ This will receive events from the children$Direction: in +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) + + + + + + + + + +**On Start** +: **tsince** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **tsince** = 0 +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeArray + +variable = SpikeArray( + id: 'a NonNegativeInteger (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + spikes: 'list of Spike(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + +``` +```` +````` + +(schema:spike)= + +## spike + + + + +extends *{ref}`schema:basespikesource`* + + + +Emits a single spike at the specified **time**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**time**$ Time at which to emit one spike event ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spiked**$ 0 signals not yet spiked, 1 signals has spiked $Dimensionless +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **this** AS **a** +: WITH **parent** AS **b** +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **spiked**: Dimensionless  (exposed as **spiked**) + + + + + + + + + +**On Start** +: **tsince** = 0 + + + +**On Conditions** + +: IF (t >= time) AND (spiked = 0) THEN +:    **spiked** = 1 +:    **tsince** = 0 +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Spike + +variable = Spike( + id: 'a NonNegativeInteger (required)' = None, + time: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:pulsegenerator)= + +## pulseGenerator + + + + +extends *{ref}`schema:basepointcurrent`* + + + +Generates a constant current pulse of a certain **amplitude** for a specified **duration** after a **delay.** Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**amplitude**$ Amplitude of current pulse ${ref}`schema:dimensions:current` +**delay**$ Delay before change in current. Current is zero prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for holding current at amplitude. Current is zero after delay + duration. ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note: this is not used here. Will be removed in future$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **i**: {ref}`schema:dimensions:current`  (exposed as **i**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **i** = 0 + +: IF t >= delay AND t < duration + delay THEN +:    **i** = weight * amplitude + +: IF t >= duration + delay THEN +:    **i** = 0 + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import PulseGenerator + +variable = PulseGenerator( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + amplitude: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:compoundinput)= + +## compoundInput + + + + +extends *{ref}`schema:basepointcurrent`* + + + +Generates a current which is the sum of all its child {ref}`schema:basepointcurrent` element, e.g. can be a combination of {ref}`schema:pulsegenerator`, {ref}`schema:sinegenerator` elements producing a single **i.** Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**currents**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + + + +**Derived Variables** + : **i_total** = currents[*]->i(reduce method: add) + : **i** = weight * i_total (exposed as **i**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import CompoundInput + +variable = CompoundInput( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + pulse_generators: 'list of PulseGenerator(s) (optional)' = None, + sine_generators: 'list of SineGenerator(s) (optional)' = None, + ramp_generators: 'list of RampGenerator(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + +``` +```` +````` + +(schema:compoundinputdl)= + +## compoundInputDL + + + + +extends *{ref}`schema:basepointcurrentdl`* + + + +Generates a current which is the sum of all its child {ref}`schema:basepointcurrentdl` elements, e.g. can be a combination of {ref}`schema:pulsegeneratordl`, {ref}`schema:sinegeneratordl` elements producing a single **i.** Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**currents**$ $ {ref}`schema:basepointcurrentdl` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrentdl`)* $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + + + +**Derived Variables** + : **I_total** = currents[*]->I(reduce method: add) + : **I** = weight * I_total (exposed as **I**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import CompoundInputDL + +variable = CompoundInputDL( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + pulse_generator_dls: 'list of PulseGeneratorDL(s) (optional)' = None, + sine_generator_dls: 'list of SineGeneratorDL(s) (optional)' = None, + ramp_generator_dls: 'list of RampGeneratorDL(s) (optional)' = None, +) +``` +```` +````` + +(schema:pulsegeneratordl)= + +## pulseGeneratorDL + + + + +extends *{ref}`schema:basepointcurrentdl`* + + + +Dimensionless equivalent of {ref}`schema:pulsegenerator`. Generates a constant current pulse of a certain **amplitude** for a specified **duration** after a **delay.** Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**amplitude**$ Amplitude of current pulse $Dimensionless +**delay**$ Delay before change in current. Current is zero prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for holding current at amplitude. Current is zero after delay + duration. ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrentdl`)* $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **I**: Dimensionless  (exposed as **I**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **I** = 0 + +: IF t >= delay AND t < duration + delay THEN +:    **I** = weight * amplitude + +: IF t >= duration + delay THEN +:    **I** = 0 + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import PulseGeneratorDL + +variable = PulseGeneratorDL( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + amplitude: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````` + +(schema:sinegenerator)= + +## sineGenerator + + + + +extends *{ref}`schema:basepointcurrent`* + + + +Generates a sinusoidally varying current after a time **delay,** for a fixed **duration.** The **period** and maximum **amplitude** of the current can be set as well as the **phase** at which to start. Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**amplitude**$ Maximum amplitude of current ${ref}`schema:dimensions:current` +**delay**$ Delay before change in current. Current is zero prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for holding current at amplitude. Current is zero after delay + duration. ${ref}`schema:dimensions:time` +**period**$ Time period of oscillation ${ref}`schema:dimensions:time` +**phase**$ Phase (between 0 and 2*pi) at which to start the varying current (i.e. at time given by delay) $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ $Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **i**: {ref}`schema:dimensions:current`  (exposed as **i**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **i** = 0 + +: IF t >= delay AND t < duration+delay THEN +:    **i** = weight * amplitude * sin(phase + (2 * 3.14159265 * (t-delay)/period) ) + +: IF t >= duration+delay THEN +:    **i** = 0 + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SineGenerator + +variable = SineGenerator( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + phase: 'a Nml2Quantity_none (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + amplitude: 'a Nml2Quantity_current (required)' = None, + period: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:sinegeneratordl)= + +## sineGeneratorDL + + + + +extends *{ref}`schema:basepointcurrentdl`* + + + +Dimensionless equivalent of {ref}`schema:sinegenerator`. Generates a sinusoidally varying current after a time **delay,** for a fixed **duration.** The **period** and maximum **amplitude** of the current can be set as well as the **phase** at which to start. Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**amplitude**$ Maximum amplitude of current $Dimensionless +**delay**$ Delay before change in current. Current is zero prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for holding current at amplitude. Current is zero after delay + duration. ${ref}`schema:dimensions:time` +**period**$ Time period of oscillation ${ref}`schema:dimensions:time` +**phase**$ Phase (between 0 and 2*pi) at which to start the varying current (i.e. at time given by delay) $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrentdl`)* $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ $Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **I**: Dimensionless  (exposed as **I**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **I** = 0 + +: IF t >= delay AND t < duration+delay THEN +:    **I** = weight * amplitude * sin(phase + (2 * 3.14159265 * (t-delay)/period) ) + +: IF t >= duration+delay THEN +:    **I** = 0 + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SineGeneratorDL + +variable = SineGeneratorDL( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + phase: 'a Nml2Quantity_none (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + amplitude: 'a Nml2Quantity_current (required)' = None, + period: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````` + +(schema:rampgenerator)= + +## rampGenerator + + + + +extends *{ref}`schema:basepointcurrent`* + + + +Generates a ramping current after a time **delay,** for a fixed **duration.** During this time the current steadily changes from **startAmplitude** to **finishAmplitude.** Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**baselineAmplitude**$ Amplitude of current before time delay, and after time delay + duration ${ref}`schema:dimensions:current` +**delay**$ Delay before change in current. Current is baselineAmplitude prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for holding current at amplitude. Current is baselineAmplitude after delay + duration. ${ref}`schema:dimensions:time` +**finishAmplitude**$ Amplitude of linearly varying current at time delay + duration ${ref}`schema:dimensions:current` +**startAmplitude**$ Amplitude of linearly varying current at time delay ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ $Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **i**: {ref}`schema:dimensions:current`  (exposed as **i**) + + + + + + + + + +**On Start** +: **i** = baselineAmplitude + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **i** = weight * baselineAmplitude + +: IF t >= delay AND t < duration+delay THEN +:    **i** = weight * (startAmplitude + (finishAmplitude - startAmplitude) * (t - delay) / (duration)) + +: IF t >= duration+delay THEN +:    **i** = weight * baselineAmplitude + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import RampGenerator + +variable = RampGenerator( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + start_amplitude: 'a Nml2Quantity_current (required)' = None, + finish_amplitude: 'a Nml2Quantity_current (required)' = None, + baseline_amplitude: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:rampgeneratordl)= + +## rampGeneratorDL + + + + +extends *{ref}`schema:basepointcurrentdl`* + + + +Dimensionless equivalent of {ref}`schema:rampgenerator`. Generates a ramping current after a time **delay,** for a fixed **duration.** During this time the dimensionless current steadily changes from **startAmplitude** to **finishAmplitude.** Scaled by **weight,** if set. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**baselineAmplitude**$ Amplitude of current before time delay, and after time delay + duration $Dimensionless +**delay**$ Delay before change in current. Current is baselineAmplitude prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for holding current at amplitude. Current is baselineAmplitude after delay + duration. ${ref}`schema:dimensions:time` +**finishAmplitude**$ Amplitude of linearly varying current at time delay + duration $Dimensionless +**startAmplitude**$ Amplitude of linearly varying current at time delay $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrentdl`)* $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ $Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **I**: Dimensionless  (exposed as **I**) + + + + + + + + + +**On Start** +: **I** = baselineAmplitude + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **I** = weight * baselineAmplitude + +: IF t >= delay AND t < duration+delay THEN +:    **I** = weight * (startAmplitude + (finishAmplitude - startAmplitude) * (t - delay) / (duration)) + +: IF t >= duration+delay THEN +:    **I** = weight * baselineAmplitude + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import RampGeneratorDL + +variable = RampGeneratorDL( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + start_amplitude: 'a Nml2Quantity_current (required)' = None, + finish_amplitude: 'a Nml2Quantity_current (required)' = None, + baseline_amplitude: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````` + +(schema:voltageclamp)= + +## voltageClamp + + + + +extends *{ref}`schema:basevoltagedeppointcurrent`* + + + +Voltage clamp. Applies a variable current **i** to try to keep parent at **targetVoltage.** Not yet fully tested!!! Consider using voltageClampTriple!! + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**delay**$ Delay before change in current. Current is zero prior to this. ${ref}`schema:dimensions:time` +**duration**$ Duration for attempting to keep parent at targetVoltage. Current is zero after delay + duration. ${ref}`schema:dimensions:time` +**simpleSeriesResistance**$ Current will be calculated by the difference in voltage between the target and parent, divided by this value ${ref}`schema:dimensions:resistance` +**targetVoltage**$ Current will be applied to try to get parent to this target voltage ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **i**: {ref}`schema:dimensions:current`  (exposed as **i**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF t < delay THEN +:    **i** = 0 + +: IF t >= delay THEN +:    **i** = weight * (targetVoltage - v) / simpleSeriesResistance + +: IF t > duration + delay THEN +:    **i** = 0 + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import VoltageClamp + +variable = VoltageClamp( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + target_voltage: 'a Nml2Quantity_voltage (required)' = None, + simple_series_resistance: 'a Nml2Quantity_resistance (required)' = None, +) +``` +```` +````` + +(schema:voltageclamptriple)= + +## voltageClampTriple + + + + +extends *{ref}`schema:basevoltagedeppointcurrent`* + + + +Voltage clamp with 3 clamp levels. Applies a variable current **i** ( through **simpleSeriesResistance** ) to try to keep parent cell at **conditioningVoltage** until time **delay,** **testingVoltage** until **delay** + **duration,** and **returnVoltage** afterwards. Only enabled if **active** = 1. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**active**$ Whether the voltage clamp is active (1) or inactive (0). $Dimensionless +**conditioningVoltage**$ Target voltage before time delay ${ref}`schema:dimensions:voltage` +**delay**$ Delay before switching from conditioningVoltage to testingVoltage. ${ref}`schema:dimensions:time` +**duration**$ Duration to hold at testingVoltage. ${ref}`schema:dimensions:time` +**returnVoltage**$ Target voltage after time duration ${ref}`schema:dimensions:voltage` +**simpleSeriesResistance**$ Current will be calculated by the difference in voltage between the target and parent, divided by this value ${ref}`schema:dimensions:resistance` +**testingVoltage**$ Target voltage between times delay and delay + duration ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrent`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ Note this is not used here. Will be removed in future$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **i**: {ref}`schema:dimensions:current`  (exposed as **i**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** + + + +**On Conditions** + +: IF active = 1 AND t < delay THEN +:    **i** = weight * (conditioningVoltage - v) / simpleSeriesResistance + +: IF active = 1 AND t >= delay THEN +:    **i** = weight * (testingVoltage - v) / simpleSeriesResistance + +: IF active = 1 AND t > duration + delay THEN +:    **i** = weight * (returnVoltage - v) / simpleSeriesResistance + + + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import VoltageClampTriple + +variable = VoltageClampTriple( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + active: 'a ZeroOrOne (required)' = None, + delay: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + conditioning_voltage: 'a Nml2Quantity_voltage (required)' = None, + testing_voltage: 'a Nml2Quantity_voltage (required)' = None, + return_voltage: 'a Nml2Quantity_voltage (required)' = None, + simple_series_resistance: 'a Nml2Quantity_resistance (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` diff --git a/_sources/Userdocs/Schemas/Networks.md b/_sources/Userdocs/Schemas/Networks.md new file mode 100644 index 00000000..5cf8f04d --- /dev/null +++ b/_sources/Userdocs/Schemas/Networks.md @@ -0,0 +1,1958 @@ + +(schema:networks_)= +# Networks + +**Network descriptions for NeuroML 2. Describes {ref}`schema:network` elements containing {ref}`schema:population`s ( potentially of type {ref}`schema:populationlist`, and so specifying a list of cell {ref}`schema:location`s ), {ref}`schema:projection`s ( i.e. lists of {ref}`schema:connection`s ) and {ref}`schema:input`s.** + +--- + + +Original ComponentType definitions: [Networks.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//Networks.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:network)= + +## network + + + + +extends *{ref}`schema:basestandalone`* + + + +Network containing: {ref}`schema:population`s ( potentially of type {ref}`schema:populationlist`, and so specifying a list of cell {ref}`schema:location`s ); {ref}`schema:projection`s ( with lists of {ref}`schema:connection`s ) and/or {ref}`schema:explicitconnection`s; and {ref}`schema:inputlist`s ( with lists of {ref}`schema:input`s ) and/or {ref}`schema:explicitinput`s. Note: often in NeuroML this will be of type {ref}`schema:networkwithtemperature` if there are temperature dependent elements ( e.g. ion channels ). + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**regions**$ $ {ref}`schema:region` +**populations**$ $ {ref}`schema:basepopulation` +**projections**$ $ {ref}`schema:projection` +**synapticConnections**$ $ {ref}`schema:explicitconnection` +**electricalProjection**$ $ {ref}`schema:electricalprojection` +**continuousProjection**$ $ {ref}`schema:continuousprojection` +**explicitInputs**$ $ {ref}`schema:explicitinput` +**inputs**$ $ {ref}`schema:inputlist` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Network + +variable = Network( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + type: 'a networkTypes (optional)' = None, + temperature: 'a Nml2Quantity_temperature (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + spaces: 'list of Space(s) (optional)' = None, + regions: 'list of Region(s) (optional)' = None, + extracellular_properties: 'list of ExtracellularPropertiesLocal(s) (optional)' = None, + populations: 'list of Population(s) (required)' = None, + cell_sets: 'list of CellSet(s) (optional)' = None, + synaptic_connections: 'list of SynapticConnection(s) (optional)' = None, + projections: 'list of Projection(s) (optional)' = None, + electrical_projections: 'list of ElectricalProjection(s) (optional)' = None, + continuous_projections: 'list of ContinuousProjection(s) (optional)' = None, + explicit_inputs: 'list of ExplicitInput(s) (optional)' = None, + input_lists: 'list of InputList(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + + + + + + + + +``` +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +```{code-block} xml + + + + + + + + + +``` +```` +````` + +(schema:networkwithtemperature)= + +## networkWithTemperature + + + + +extends {ref}`schema:network` + + + +Same as {ref}`schema:network`, but with an explicit **temperature** for temperature dependent elements ( e.g. ion channels ). + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**temperature**$ ${ref}`schema:dimensions:temperature` + +``` +```` +````` + +(schema:basepopulation)= + +## *basePopulation* + + + + +extends *{ref}`schema:basestandalone`* + + + +A population of multiple instances of a specific **component,** which anything which extends {ref}`schema:basecell`. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**component**$ $ {ref}`schema:basecell` + +``` +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**notes**$ $ {ref}`schema:notes` +**annotation**$ $ {ref}`schema:annotation` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**property**$ $ {ref}`schema:property` + +``` +```` +````` + +(schema:population)= + +## population + + + + +extends *{ref}`schema:basepopulation`* + + + +A population of components, with just one parameter for the **size,** i.e. number of components to create. Note: quite often this is used with type= {ref}`schema:populationlist` which means the size is determined by the number of {ref}`schema:instance`s ( with {ref}`schema:location`s ) in the list. The **size** attribute is still set, and there will be a validation error if this does not match the number in the list. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**size**$ Number of instances of this Component to create when the population is instantiated $Dimensionless + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Population + +variable = Population( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + component: 'a NmlId (required)' = None, + size: 'a NonNegativeInteger (optional)' = None, + type: 'a populationTypes (optional)' = None, + extracellular_properties: 'a NmlId (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + layout: 'a Layout (optional)' = None, + instances: 'list of Instance(s) (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:populationlist)= + +## populationList + + + + +extends *{ref}`schema:basepopulation`* + + + +An explicit list of {ref}`schema:instance`s ( with {ref}`schema:location`s ) of components in the population. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**size**$ Note: the size of the populationList to create is set by the number of explicitly defined instances. The size attribute is still set, and there will be a validation error if this does not match the number in the list. + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**instances**$ $ {ref}`schema:instance` + +``` +```` +````` + +(schema:instance)= + +## instance + + + + +Specifies a single instance of a component in a {ref}`schema:population` ( placed at {ref}`schema:location` ). + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**location**$ $ {ref}`schema:location` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Instance + +variable = Instance( + id: 'a nonNegativeInteger (optional)' = None, + i: 'a nonNegativeInteger (optional)' = None, + j: 'a nonNegativeInteger (optional)' = None, + k: 'a nonNegativeInteger (optional)' = None, + location: 'a Location (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:location)= + +## location + + + + +Specifies the ( x, y, z ) location of a single {ref}`schema:instance` of a component in a {ref}`schema:population`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**x**$ $Dimensionless +**y**$ $Dimensionless +**z**$ $Dimensionless + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Location + +variable = Location( + x: 'a float (required)' = None, + y: 'a float (required)' = None, + z: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:region)= + +## region + + + + +Initial attempt to specify 3D region for placing cells. Work in progress... + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rectangularExtent**$ $ {ref}`schema:rectangularextent` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Region + +variable = Region( + id: 'a NmlId (required)' = None, + spaces: 'a NmlId (optional)' = None, + anytypeobjs_=None, +) +``` +```` +````` + +(schema:rectangularextent)= + +## rectangularExtent + + + + +For defining a 3D rectangular box. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**xLength**$ $Dimensionless +**xStart**$ $Dimensionless +**yLength**$ $Dimensionless +**yStart**$ $Dimensionless +**zLength**$ $Dimensionless +**zStart**$ $Dimensionless + +``` +```` +````` + +(schema:projection)= + +## projection + + + + +Projection from one population, **presynapticPopulation** to another, **postsynapticPopulation,** through **synapse.** Contains lists of {ref}`schema:connection` or {ref}`schema:connectionwd` elements. + + +`````{tab-set} +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**presynapticPopulation**$ +**postsynapticPopulation**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**connections**$ $ {ref}`schema:connection` +**connectionsWD**$ $ {ref}`schema:connectionwd` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Projection + +variable = Projection( + id: 'a NmlId (required)' = None, + presynaptic_population: 'a NmlId (required)' = None, + postsynaptic_population: 'a NmlId (required)' = None, + synapse: 'a NmlId (required)' = None, + connections: 'list of Connection(s) (optional)' = None, + connection_wds: 'list of ConnectionWD(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:explicitconnection)= + +## explicitConnection + + + + +Explicit event connection between components. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**targetPort**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**from**$ +**to**$ + +```` +````` + +(schema:connection)= + +## connection + + + + +Event connection directly between named components, which gets processed via a new instance of a **synapse** component which is created on the target component. Normally contained inside a {ref}`schema:projection` element. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**destination**$ +**preFractionAlong**$ +**postFractionAlong**$ +**preSegmentId**$ +**postSegmentId**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preCellId**$ +**postCellId**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Connection + +variable = Connection( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell_id: 'a Nml2PopulationReferencePath (required)' = None, + pre_segment_id: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell_id: 'a Nml2PopulationReferencePath (required)' = None, + post_segment_id: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:synapticconnection)= + +## synapticConnection + + + + +extends {ref}`schema:explicitconnection` + + + +Explicit event connection between named components, which gets processed via a new instance of a **synapse** component which is created on the target component. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**destination**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**from**$ +**to**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SynapticConnection + +variable = SynapticConnection( + neuro_lex_id: 'a NeuroLexId (optional)' = None, + from_: 'a Nml2PopulationReferencePath (required)' = None, + to: 'a Nml2PopulationReferencePath (required)' = None, + synapse: 'a NmlId (required)' = None, + destination: 'a NmlId (optional)' = None, +) +``` +```` +````` + +(schema:synapticconnectionwd)= + +## synapticConnectionWD + + + + +extends {ref}`schema:synapticconnection` + + + +Explicit event connection between named components, which gets processed via a new instance of a **synapse** component which is created on the target component, includes setting of **weight** and **delay** for the synaptic connection. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**delay**$ ${ref}`schema:dimensions:time` +**weight**$ $Dimensionless + +``` +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**from**$ +**to**$ + +```` +````` + +(schema:connectionwd)= + +## connectionWD + + + + +extends {ref}`schema:connection` + + + +Event connection between named components, which gets processed via a new instance of a synapse component which is created on the target component, includes setting of **weight** and **delay** for the synaptic connection. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**delay**$ ${ref}`schema:dimensions:time` +**weight**$ $Dimensionless + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**destination**$ +**preFractionAlong**$ +**postFractionAlong**$ +**preSegmentId**$ +**postSegmentId**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preCellId**$ +**postCellId**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ConnectionWD + +variable = ConnectionWD( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell_id: 'a Nml2PopulationReferencePath (required)' = None, + pre_segment_id: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell_id: 'a Nml2PopulationReferencePath (required)' = None, + post_segment_id: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + weight: 'a float (required)' = None, + delay: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:electricalconnection)= + +## electricalConnection + + + + +To enable connections between populations through gap junctions. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:gapjunction` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ElectricalConnection + +variable = ElectricalConnection( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell: 'a string (required)' = None, + pre_segment: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell: 'a string (required)' = None, + post_segment: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + synapse: 'a NmlId (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:electricalconnectioninstance)= + +## electricalConnectionInstance + + + + +To enable connections between populations through gap junctions. Populations need to be of type {ref}`schema:populationlist` and contain {ref}`schema:instance` and {ref}`schema:location` elements. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preFractionAlong**$ +**postFractionAlong**$ +**preSegment**$ +**postSegment**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preCell**$ +**postCell**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse**$ $ {ref}`schema:gapjunction` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ElectricalConnectionInstance + +variable = ElectricalConnectionInstance( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell: 'a string (required)' = None, + pre_segment: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell: 'a string (required)' = None, + post_segment: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + synapse: 'a NmlId (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:electricalconnectioninstancew)= + +## electricalConnectionInstanceW + + + + +extends {ref}`schema:electricalconnectioninstance` + + + +To enable connections between populations through gap junctions. Populations need to be of type {ref}`schema:populationlist` and contain {ref}`schema:instance` and {ref}`schema:location` elements. Includes setting of **weight** for the connection. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**weight**$ $Dimensionless + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preFractionAlong**$ +**postFractionAlong**$ +**preSegment**$ +**postSegment**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preCell**$ +**postCell**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ElectricalConnectionInstanceW + +variable = ElectricalConnectionInstanceW( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell: 'a string (required)' = None, + pre_segment: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell: 'a string (required)' = None, + post_segment: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + synapse: 'a NmlId (required)' = None, + weight: 'a float (required)' = None, +) +``` +```` +````` + +(schema:electricalprojection)= + +## electricalProjection + + + + +A projection between **presynapticPopulation** to another **postsynapticPopulation** through gap junctions. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**presynapticPopulation**$ $ {ref}`schema:population` +**postsynapticPopulation**$ $ {ref}`schema:population` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**connections**$ $ {ref}`schema:electricalconnection` +**connectionInstances**$ $ {ref}`schema:electricalconnectioninstance` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ElectricalProjection + +variable = ElectricalProjection( + id: 'a NmlId (required)' = None, + presynaptic_population: 'a NmlId (required)' = None, + postsynaptic_population: 'a NmlId (required)' = None, + electrical_connections: 'list of ElectricalConnection(s) (optional)' = None, + electrical_connection_instances: 'list of ElectricalConnectionInstance(s) (optional)' = None, + electrical_connection_instance_ws: 'list of ElectricalConnectionInstanceW(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:continuousconnection)= + +## continuousConnection + + + + +An instance of a connection in a {ref}`schema:continuousprojection` between **presynapticPopulation** to another **postsynapticPopulation** through a **preComponent** at the start and **postComponent** at the end. Can be used for analog synapses. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**preComponent**$ $ {ref}`schema:basegradedsynapse` +**postComponent**$ $ {ref}`schema:basegradedsynapse` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ContinuousConnection + +variable = ContinuousConnection( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell: 'a string (required)' = None, + pre_segment: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell: 'a string (required)' = None, + post_segment: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + pre_component: 'a NmlId (required)' = None, + post_component: 'a NmlId (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:continuousconnectioninstance)= + +## continuousConnectionInstance + + + + +An instance of a connection in a {ref}`schema:continuousprojection` between **presynapticPopulation** to another **postsynapticPopulation** through a **preComponent** at the start and **postComponent** at the end. Populations need to be of type {ref}`schema:populationlist` and contain {ref}`schema:instance` and {ref}`schema:location` elements. Can be used for analog synapses. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preFractionAlong**$ +**postFractionAlong**$ +**preSegment**$ +**postSegment**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preCell**$ +**postCell**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**preComponent**$ $ {ref}`schema:basegradedsynapse` +**postComponent**$ $ {ref}`schema:basegradedsynapse` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ContinuousConnectionInstance + +variable = ContinuousConnectionInstance( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell: 'a string (required)' = None, + pre_segment: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell: 'a string (required)' = None, + post_segment: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + pre_component: 'a NmlId (required)' = None, + post_component: 'a NmlId (required)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:continuousconnectioninstancew)= + +## continuousConnectionInstanceW + + + + +extends {ref}`schema:continuousconnectioninstance` + + + +An instance of a connection in a {ref}`schema:continuousprojection` between **presynapticPopulation** to another **postsynapticPopulation** through a **preComponent** at the start and **postComponent** at the end. Populations need to be of type {ref}`schema:populationlist` and contain {ref}`schema:instance` and {ref}`schema:location` elements. Can be used for analog synapses. Includes setting of **weight** for the connection. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**weight**$ $Dimensionless + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preFractionAlong**$ +**postFractionAlong**$ +**preSegment**$ +**postSegment**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**preCell**$ +**postCell**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ContinuousConnectionInstanceW + +variable = ContinuousConnectionInstanceW( + id: 'a NonNegativeInteger (required)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + pre_cell: 'a string (required)' = None, + pre_segment: 'a NonNegativeInteger (optional)' = '0', + pre_fraction_along: 'a ZeroToOne (optional)' = '0.5', + post_cell: 'a string (required)' = None, + post_segment: 'a NonNegativeInteger (optional)' = '0', + post_fraction_along: 'a ZeroToOne (optional)' = '0.5', + pre_component: 'a NmlId (required)' = None, + post_component: 'a NmlId (required)' = None, + weight: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:continuousprojection)= + +## continuousProjection + + + + +A projection between **presynapticPopulation** and **postsynapticPopulation** through components **preComponent** at the start and **postComponent** at the end of a {ref}`schema:continuousconnection` or {ref}`schema:continuousconnectioninstance`. Can be used for analog synapses. + + +`````{tab-set} +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**presynapticPopulation**$ $ {ref}`schema:population` +**postsynapticPopulation**$ $ {ref}`schema:population` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**connections**$ $ {ref}`schema:continuousconnection` +**connectionInstances**$ $ {ref}`schema:continuousconnectioninstance` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ContinuousProjection + +variable = ContinuousProjection( + id: 'a NmlId (required)' = None, + presynaptic_population: 'a NmlId (required)' = None, + postsynaptic_population: 'a NmlId (required)' = None, + continuous_connections: 'list of ContinuousConnection(s) (optional)' = None, + continuous_connection_instances: 'list of ContinuousConnectionInstance(s) (optional)' = None, + continuous_connection_instance_ws: 'list of ContinuousConnectionInstanceW(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:explicitinput)= + +## explicitInput + + + + +An explicit input ( anything which extends {ref}`schema:basepointcurrent` ) to a target cell in a population. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**destination**$ +**sourcePort**$ +**targetPort**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**target**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**input**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ExplicitInput + +variable = ExplicitInput( + target: 'a Nml2PopulationReferencePath (required)' = None, + input: 'a NmlId (required)' = None, + destination: 'a NmlId (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:inputlist)= + +## inputList + + + + +An explicit list of {ref}`schema:input`s to a **population.**. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**population**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**component**$ $ {ref}`schema:basepointcurrent` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**inputs**$ $ {ref}`schema:input` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import InputList + +variable = InputList( + id: 'a NonNegativeInteger (required)' = None, + populations: 'a NmlId (required)' = None, + component: 'a NmlId (required)' = None, + input: 'list of Input(s) (optional)' = None, + input_ws: 'list of InputW(s) (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```{code-block} xml + + + +``` +```` +````` + +(schema:input)= + +## input + + + + +Specifies a single input to a **target,** optionally giving the **segmentId** ( default 0 ) and **fractionAlong** the segment ( default 0.5 ). + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**segmentId**$ Optional specification of the segment to target, default 0 +**fractionAlong**$ Optional specification of the fraction along the specified segment, default 0.5 +**destination**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**target**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Input + +variable = Input( + id: 'a NonNegativeInteger (required)' = None, + target: 'a Nml2PopulationReferencePath (required)' = None, + destination: 'a NmlId (required)' = None, + segment_id: 'a NonNegativeInteger (optional)' = None, + fraction_along: 'a ZeroToOne (optional)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:inputw)= + +## inputW + + + + +extends {ref}`schema:input` + + + +Specifies input lists. Can set **weight** to scale individual inputs. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**weight**$ $Dimensionless + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**destination**$ + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**target**$ + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import InputW + +variable = InputW( + id: 'a NonNegativeInteger (required)' = None, + target: 'a Nml2PopulationReferencePath (required)' = None, + destination: 'a NmlId (required)' = None, + segment_id: 'a NonNegativeInteger (optional)' = None, + fraction_along: 'a ZeroToOne (optional)' = None, + weight: 'a float (required)' = None, +) +``` +```` +````` diff --git a/_sources/Userdocs/Schemas/NeuroMLCoreCompTypes.md b/_sources/Userdocs/Schemas/NeuroMLCoreCompTypes.md new file mode 100644 index 00000000..3343028b --- /dev/null +++ b/_sources/Userdocs/Schemas/NeuroMLCoreCompTypes.md @@ -0,0 +1,731 @@ + +(schema:neuromlcorecomptypes_)= +# NeuroMLCoreCompTypes + + + + +Original ComponentType definitions: [NeuroMLCoreCompTypes.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//NeuroMLCoreCompTypes.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:notes)= + +## notes + + + + +Human readable notes/description for a Component. + + +`````{tab-set} +````{tab-item} Schema +```{code-block} xml + + + Textual human readable notes related to the element in question. It's useful to put these into + the NeuroML files instead of XML comments, as the notes can be extracted and repeated in the files to which the NeuroML is mapped. + + + + + +``` +```` + + +````{tab-item} Usage: XML +```{code-block} xml +A Simple Spiking cell for testing purposes +``` +```{code-block} xml +Multicompartmental cell +``` +```{code-block} xml +Leak conductance +``` +```` +````` + +(schema:annotation)= + +## annotation + + + + +A structured annotation containing metadata, specifically RDF or {ref}`schema:property` elements. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rdf:RDF**$ $ {ref}`schema:rdf_rdf` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**property**$ $ {ref}`schema:property` + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Annotation + +variable = Annotation( + anytypeobjs_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + + + + + + + + + + +``` +```` +````` + +(schema:property)= + +## property + + + + +A property ( a **tag** and **value** pair ), which can be on any {ref}`schema:basestandalone` either as a direct child, or within an {ref}`schema:annotation`. Generally something which helps the visual display or facilitates simulation of a Component, but is not a core physiological property. Common examples include: **numberInternalDivisions,** equivalent of nseg in NEURON; **radius,** for a radius to use in graphical displays for abstract cells ( i.e. without defined morphologies ); **color,** the color to use for a {ref}`schema:population` or {ref}`schema:populationlist` of cells; **recommended_dt_ms,** the recommended timestep to use for simulating a {ref}`schema:network`, **recommended_duration_ms** the recommended duration to use when running a {ref}`schema:network`. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**tag**$ Name of the property +**value**$ Value of the property + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Property + +variable = Property( + tag: 'a string (required)' = None, + value: 'a string (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:basestandalone)= + +## *baseStandalone* + + + + +Base type of any Component which can have {ref}`schema:notes`, {ref}`schema:annotation`, or a {ref}`schema:property` list. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**notes**$ $ {ref}`schema:notes` +**annotation**$ $ {ref}`schema:annotation` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**property**$ $ {ref}`schema:property` + +``` +```` +````` + +(schema:rdf_rdf)= + +## rdf_RDF + + + + +Structured block in an {ref}`schema:annotation` based on RDF. See https://github.com/OpenSourceBrain/OSB_API/blob/master/python/examples/grancelllayer.xml. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**xmlns:rdf**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rdf:Description**$ $ {ref}`schema:rdf_description` + +``` +```` +````` + +(schema:rdf_description)= + +## rdf_Description + + + + +Structured block in an {ref}`schema:annotation` based on RDF. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**rdf:about**$ + +```` + +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**bqbiol:encodes**$ $ {ref}`schema:bqbiol_encodes` +**bqbiol:hasPart**$ $ {ref}`schema:bqbiol_haspart` +**bqbiol:hasProperty**$ $ {ref}`schema:bqbiol_hasproperty` +**bqbiol:hasVersion**$ $ {ref}`schema:bqbiol_hasversion` +**bqbiol:is**$ $ {ref}`schema:bqbiol_is` +**bqbiol:isDescribedBy**$ $ {ref}`schema:bqbiol_isdescribedby` +**bqbiol:isEncodedBy**$ $ {ref}`schema:bqbiol_isencodedby` +**bqbiol:isHomologTo**$ $ {ref}`schema:bqbiol_ishomologto` +**bqbiol:isPartOf**$ $ {ref}`schema:bqbiol_ispartof` +**bqbiol:isPropertyOf**$ $ {ref}`schema:bqbiol_ispropertyof` +**bqbiol:isVersionOf**$ $ {ref}`schema:bqbiol_isversionof` +**bqbiol:occursIn**$ $ {ref}`schema:bqbiol_occursin` +**bqbiol:hasTaxon**$ $ {ref}`schema:bqbiol_hastaxon` +**bqmodel:is**$ $ {ref}`schema:bqmodel_is` +**bqmodel:isDescribedBy**$ $ {ref}`schema:bqmodel_isdescribedby` +**bqmodel:isDerivedFrom**$ $ {ref}`schema:bqmodel_isderivedfrom` + +``` +```` +````` + +(schema:basebqbiol)= + +## *baseBqbiol* + + + + +Structured block in an {ref}`schema:annotation` based on RDF. + + +`````{tab-set} +````{tab-item} Child list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rdf:Bag**$ $ {ref}`schema:rdf_bag` + +``` +```` +````` + +(schema:bqbiol_encodes)= + +## bqbiol_encodes + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_haspart)= + +## bqbiol_hasPart + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_hasproperty)= + +## bqbiol_hasProperty + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_hasversion)= + +## bqbiol_hasVersion + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_is)= + +## bqbiol_is + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_isdescribedby)= + +## bqbiol_isDescribedBy + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_isencodedby)= + +## bqbiol_isEncodedBy + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_ishomologto)= + +## bqbiol_isHomologTo + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_ispartof)= + +## bqbiol_isPartOf + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_ispropertyof)= + +## bqbiol_isPropertyOf + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_isversionof)= + +## bqbiol_isVersionOf + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**xmlns:bqbiol**$ + +```` +````` + +(schema:bqbiol_occursin)= + +## bqbiol_occursIn + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqbiol_hastaxon)= + +## bqbiol_hasTaxon + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqmodel_is)= + +## bqmodel_is + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:bqmodel_isdescribedby)= + +## bqmodel_isDescribedBy + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**xmlns:bqmodel**$ + +```` +````` + +(schema:bqmodel_isderivedfrom)= + +## bqmodel_isDerivedFrom + + + + +extends *{ref}`schema:basebqbiol`* + + + +See http://co.mbine.org/standards/qualifiers. + + + +(schema:rdf_bag)= + +## rdf_Bag + + + + +Structured block in an {ref}`schema:annotation` based on RDF. + + +`````{tab-set} +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**rdf:li**$ $ {ref}`schema:rdf:li` + +``` +```` +````` + +(schema:rdf_li)= + +## rdf_li + + + + +Structured block in an {ref}`schema:annotation` based on RDF. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**rdf:resource**$ + +```` +````` + +(schema:point3dwithdiam)= + +## point3DWithDiam + + + + +Base type for ComponentTypes which specify an ( **x,** **y,** **z** ) coordinate along with a **diameter.** Note: no dimension used in the attributes for these coordinates! These are assumed to have dimension micrometer ( 10^-6 m ). This is due to micrometers being the default option for the majority of neuronal morphology formats, and dimensions are omitted here to facilitate reading and writing of morphologies in NeuroML. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**diameter**$ Diameter of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. $Dimensionless +**x**$ x coordinate of the point. Note: no dimension used, see description of _point3DWithDiam_ for details. $Dimensionless +**y**$ y coordinate of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. $Dimensionless +**z**$ z coordinate of the ppoint. Note: no dimension used, see description of _point3DWithDiam_ for details. $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MICRON** = 1um$ $ {ref}`schema:dimensions:length` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**radius**$ A dimensional quantity given by half the _diameter. ${ref}`schema:dimensions:length` +``` +   **radius** = MICRON * diameter / 2 +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**xLength**$ A version of _x with dimension length. ${ref}`schema:dimensions:length` +``` +   **xLength** = MICRON * x +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**yLength**$ A version of _y with dimension length. ${ref}`schema:dimensions:length` +``` +   **yLength** = MICRON * y +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**zLength**$ A version of _z with dimension length. ${ref}`schema:dimensions:length` +``` +   **zLength** = MICRON * z + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import Point3DWithDiam + +variable = Point3DWithDiam( + x: 'a double (required)' = None, + y: 'a double (required)' = None, + z: 'a double (required)' = None, + diameter: 'a DoubleGreaterThanZero (required)' = None, +) +``` +```` +````` diff --git a/_sources/Userdocs/Schemas/NeuroMLCoreDimensions.md b/_sources/Userdocs/Schemas/NeuroMLCoreDimensions.md new file mode 100644 index 00000000..98e5c81d --- /dev/null +++ b/_sources/Userdocs/Schemas/NeuroMLCoreDimensions.md @@ -0,0 +1,2497 @@ + +(schema:neuromlcoredimensions_)= +# NeuroMLCoreDimensions + + + + +Original ComponentType definitions: [NeuroMLCoreDimensions.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//NeuroMLCoreDimensions.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:dimensions:*)= +## Dimensions + +(schema:dimensions:area)= +### area + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:cm2` + +- Defined unit: {ref}`schema:units:m2` + +- Defined unit: {ref}`schema:units:um2` + +```` + + + +````` + +(schema:dimensions:capacitance)= +### capacitance + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`-1` L{superscript}`-2` T{superscript}`4` I{superscript}`2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:F` + +- Defined unit: {ref}`schema:units:nF` + +- Defined unit: {ref}`schema:units:pF` + +- Defined unit: {ref}`schema:units:uF` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:charge)= +### charge + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +T{superscript}`1` I{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:C` + +- Defined unit: {ref}`schema:units:e` + +```` + + + +````` + +(schema:dimensions:charge_per_mole)= +### charge\_per\_mole + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +T{superscript}`1` I{superscript}`1` N{superscript}`-1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:C_per_mol` + +- Defined unit: {ref}`schema:units:nA_ms_per_amol` + +- Defined unit: {ref}`schema:units:pC_per_umol` + +```` + + + +````` + +(schema:dimensions:concentration)= +### concentration + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`-3` N{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:M` + +- Defined unit: {ref}`schema:units:mM` + +- Defined unit: {ref}`schema:units:mol_per_cm3` + +- Defined unit: {ref}`schema:units:mol_per_m3` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:conductance)= +### conductance + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`-1` L{superscript}`-2` T{superscript}`3` I{superscript}`2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:S` + +- Defined unit: {ref}`schema:units:mS` + +- Defined unit: {ref}`schema:units:nS` + +- Defined unit: {ref}`schema:units:pS` + +- Defined unit: {ref}`schema:units:uS` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:conductanceDensity)= +### conductanceDensity + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`-1` L{superscript}`-4` T{superscript}`3` I{superscript}`2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:S_per_cm2` + +- Defined unit: {ref}`schema:units:S_per_m2` + +- Defined unit: {ref}`schema:units:mS_per_cm2` + +- Defined unit: {ref}`schema:units:uS_per_cm2` + +```` + + + +````` + +(schema:dimensions:conductance_per_voltage)= +### conductance\_per\_voltage + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`-2` L{superscript}`-4` T{superscript}`6` I{superscript}`3` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:S_per_V` + +- Defined unit: {ref}`schema:units:nS_per_mV` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:current)= +### current + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +I{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:A` + +- Defined unit: {ref}`schema:units:nA` + +- Defined unit: {ref}`schema:units:pA` + +- Defined unit: {ref}`schema:units:uA` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:currentDensity)= +### currentDensity + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`-2` I{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:A_per_m2` + +- Defined unit: {ref}`schema:units:mA_per_cm2` + +- Defined unit: {ref}`schema:units:uA_per_cm2` + +```` + + + +````` + +(schema:dimensions:idealGasConstantDims)= +### idealGasConstantDims + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`1` L{superscript}`2` T{superscript}`-2` K{superscript}`-1` N{superscript}`-1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:J_per_K_per_mol` + +- Defined unit: {ref}`schema:units:fJ_per_K_per_umol` + +```` + + + +````` + +(schema:dimensions:length)= +### length + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:cm` + +- Defined unit: {ref}`schema:units:m__` + +- Defined unit: {ref}`schema:units:um` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:per_time)= +### per\_time + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +T{superscript}`-1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:Hz` + +- Defined unit: {ref}`schema:units:per_hour` + +- Defined unit: {ref}`schema:units:per_min` + +- Defined unit: {ref}`schema:units:per_ms` + +- Defined unit: {ref}`schema:units:per_s` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:per_voltage)= +### per\_voltage + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`-1` L{superscript}`-2` T{superscript}`3` I{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:per_V` + +- Defined unit: {ref}`schema:units:per_mV` + +```` + + + +````` + +(schema:dimensions:permeability)= +### permeability + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`1` T{superscript}`-1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:cm_per_ms` + +- Defined unit: {ref}`schema:units:cm_per_s` + +- Defined unit: {ref}`schema:units:m_per_s` + +- Defined unit: {ref}`schema:units:um_per_ms` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:resistance)= +### resistance + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`1` L{superscript}`2` T{superscript}`-3` I{superscript}`-2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:Mohm` + +- Defined unit: {ref}`schema:units:kohm` + +- Defined unit: {ref}`schema:units:ohm` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:resistivity)= +### resistivity + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`2` L{superscript}`2` T{superscript}`-3` I{superscript}`-2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:kohm_cm` + +- Defined unit: {ref}`schema:units:ohm_cm` + +- Defined unit: {ref}`schema:units:ohm_m` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + + + + +``` +```` + +````` + +(schema:dimensions:rho_factor)= +### rho\_factor + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`-1` T{superscript}`-1` I{superscript}`-1` N{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:mol_per_cm_per_uA_per_ms` + +- Defined unit: {ref}`schema:units:mol_per_m_per_A_per_s` + +- Defined unit: {ref}`schema:units:umol_per_cm_per_nA_per_ms` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:specificCapacitance)= +### specificCapacitance + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`-1` L{superscript}`-4` T{superscript}`4` I{superscript}`2` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:F_per_m2` + +- Defined unit: {ref}`schema:units:uF_per_cm2` + +```` + + + +````` + +(schema:dimensions:substance)= +### substance + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +N{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:mol` + +```` + + + +````` + +(schema:dimensions:temperature)= +### temperature + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +K{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:K` + +- Defined unit: {ref}`schema:units:degC` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:time)= +### time + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +T{superscript}`1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:hour` + +- Defined unit: {ref}`schema:units:min` + +- Defined unit: {ref}`schema:units:ms__` + +- Defined unit: {ref}`schema:units:s__` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:voltage)= +### voltage + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +M{superscript}`1` L{superscript}`2` T{superscript}`-3` I{superscript}`-1` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:V` + +- Defined unit: {ref}`schema:units:mV` + +```` + + +````{grid-item-card} Schema +:columns: 12 +```{code-block} xml + + + + + + +``` +```` + +````` + +(schema:dimensions:volume)= +### volume + +`````{grid} +:gutter: 2 + + +````{grid-item-card} Dimensions +:columns: 6 +L{superscript}`3` +```` + +````{grid-item-card} Units +:columns: 6 + +- Defined unit: {ref}`schema:units:cm3` + +- Defined unit: {ref}`schema:units:litre` + +- Defined unit: {ref}`schema:units:m3` + +- Defined unit: {ref}`schema:units:um3` + +```` + + + +````` + + + +## Units + +(schema:units:A)= +### A + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:current` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 A = 1.00e+09 {ref}`schema:units:nA` +- 1 A = 1.00e+12 {ref}`schema:units:pA` +- 1 A = 1.00e+06 {ref}`schema:units:uA` + +``` +```` + +(schema:units:A_per_m2)= +### A_per_m2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:currentDensity` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 A_per_m2 = 0.1 {ref}`schema:units:mA_per_cm2` +- 1 A_per_m2 = 100 {ref}`schema:units:uA_per_cm2` + +``` +```` + +(schema:units:C)= +### C + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:charge` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 C = 6.24e+18 {ref}`schema:units:e` + +``` +```` + +(schema:units:C_per_mol)= +### C_per_mol + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:charge_per_mole` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 C_per_mol = 1e-06 {ref}`schema:units:nA_ms_per_amol` +- 1 C_per_mol = 1.00e+06 {ref}`schema:units:pC_per_umol` + +``` +```` + +(schema:units:F)= +### F + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:capacitance` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 F = 1.00e+09 {ref}`schema:units:nF` +- 1 F = 1.00e+12 {ref}`schema:units:pF` +- 1 F = 1.00e+06 {ref}`schema:units:uF` + +``` +```` + +(schema:units:F_per_m2)= +### F_per_m2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:specificCapacitance` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 F_per_m2 = 100 {ref}`schema:units:uF_per_cm2` + +``` +```` + +(schema:units:Hz)= +### Hz + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_time` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 Hz = 3600 {ref}`schema:units:per_hour` +- 1 Hz = 60 {ref}`schema:units:per_min` +- 1 Hz = 0.001 {ref}`schema:units:per_ms` +- 1 Hz = 1 {ref}`schema:units:per_s` + +``` +```` + +(schema:units:J_per_K_per_mol)= +### J_per_K_per_mol + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:idealGasConstantDims` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 J_per_K_per_mol = 1.00e+09 {ref}`schema:units:fJ_per_K_per_umol` + +``` +```` + +(schema:units:K)= +### K + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:temperature` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 K = -272.15 {ref}`schema:units:degC` + +``` +```` + +(schema:units:M)= +### M + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:concentration` +- Power of 10: 3 + + + +``` + +```{grid-item-card} Conversions + +- 1 M = 1000 {ref}`schema:units:mM` +- 1 M = 0.001 {ref}`schema:units:mol_per_cm3` +- 1 M = 1000 {ref}`schema:units:mol_per_m3` + +``` +```` + +(schema:units:Mohm)= +### Mohm + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:resistance` +- Power of 10: 6 + + + +``` + +```{grid-item-card} Conversions + +- 1 Mohm = 1000 {ref}`schema:units:kohm` +- 1 Mohm = 1.00e+06 {ref}`schema:units:ohm` + +``` +```` + +(schema:units:S)= +### S + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 S = 1000 {ref}`schema:units:mS` +- 1 S = 1.00e+09 {ref}`schema:units:nS` +- 1 S = 1.00e+12 {ref}`schema:units:pS` +- 1 S = 1.00e+06 {ref}`schema:units:uS` + +``` +```` + +(schema:units:S_per_V)= +### S_per_V + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance_per_voltage` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 S_per_V = 1.00e+06 {ref}`schema:units:nS_per_mV` + +``` +```` + +(schema:units:S_per_cm2)= +### S_per_cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductanceDensity` +- Power of 10: 4 + + + +``` + +```{grid-item-card} Conversions + +- 1 S_per_cm2 = 10000 {ref}`schema:units:S_per_m2` +- 1 S_per_cm2 = 1000 {ref}`schema:units:mS_per_cm2` +- 1 S_per_cm2 = 1.00e+06 {ref}`schema:units:uS_per_cm2` + +``` +```` + +(schema:units:S_per_m2)= +### S_per_m2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductanceDensity` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 S_per_m2 = 0.0001 {ref}`schema:units:S_per_cm2` +- 1 S_per_m2 = 0.1 {ref}`schema:units:mS_per_cm2` +- 1 S_per_m2 = 100 {ref}`schema:units:uS_per_cm2` + +``` +```` + +(schema:units:V)= +### V + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:voltage` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 V = 1000 {ref}`schema:units:mV` + +``` +```` + +(schema:units:cm)= +### cm + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:length` +- Power of 10: -2 + + + +``` + +```{grid-item-card} Conversions + +- 1 cm = 0.01 {ref}`schema:units:m__` +- 1 cm = 10000 {ref}`schema:units:um` + +``` +```` + +(schema:units:cm2)= +### cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:area` +- Power of 10: -4 + + + +``` + +```{grid-item-card} Conversions + +- 1 cm2 = 0.0001 {ref}`schema:units:m2` +- 1 cm2 = 1.00e+08 {ref}`schema:units:um2` + +``` +```` + +(schema:units:cm3)= +### cm3 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:volume` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 cm3 = 0.001 {ref}`schema:units:litre` +- 1 cm3 = 1e-06 {ref}`schema:units:m3` +- 1 cm3 = 1.00e+12 {ref}`schema:units:um3` + +``` +```` + +(schema:units:cm_per_ms)= +### cm_per_ms + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:permeability` +- Power of 10: 1 + + + +``` + +```{grid-item-card} Conversions + +- 1 cm_per_ms = 1000 {ref}`schema:units:cm_per_s` +- 1 cm_per_ms = 10 {ref}`schema:units:m_per_s` +- 1 cm_per_ms = 10000 {ref}`schema:units:um_per_ms` + +``` +```` + +(schema:units:cm_per_s)= +### cm_per_s + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:permeability` +- Power of 10: -2 + + + +``` + +```{grid-item-card} Conversions + +- 1 cm_per_s = 0.001 {ref}`schema:units:cm_per_ms` +- 1 cm_per_s = 0.01 {ref}`schema:units:m_per_s` +- 1 cm_per_s = 10 {ref}`schema:units:um_per_ms` + +``` +```` + +(schema:units:degC)= +### degC + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:temperature` +- Power of 10: 0 +- Offset: 273.15 + + + +``` + +```{grid-item-card} Conversions + +- 1 degC = 274.15 {ref}`schema:units:K` + +``` +```` + +(schema:units:e)= +### e + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:charge` +- Power of 10: 0 + + +- Scale: 1.602176634e-19 + + +``` + +```{grid-item-card} Conversions + +- 1 e = 1.6022e-19 {ref}`schema:units:C` + +``` +```` + +(schema:units:fJ_per_K_per_umol)= +### fJ_per_K_per_umol + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:idealGasConstantDims` +- Power of 10: -9 + + + +``` + +```{grid-item-card} Conversions + +- 1 fJ_per_K_per_umol = 1e-09 {ref}`schema:units:J_per_K_per_mol` + +``` +```` + +(schema:units:hour)= +### hour + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:time` +- Power of 10: 0 + + +- Scale: 3600.0 + + +``` + +```{grid-item-card} Conversions + +- 1 hour = 60 {ref}`schema:units:min` +- 1 hour = 3.60e+06 {ref}`schema:units:ms__` +- 1 hour = 3600 {ref}`schema:units:s__` + +``` +```` + +(schema:units:kohm)= +### kohm + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:resistance` +- Power of 10: 3 + + + +``` + +```{grid-item-card} Conversions + +- 1 kohm = 0.001 {ref}`schema:units:Mohm` +- 1 kohm = 1000 {ref}`schema:units:ohm` + +``` +```` + +(schema:units:kohm_cm)= +### kohm_cm + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:resistivity` +- Power of 10: 1 + + + +``` + +```{grid-item-card} Conversions + +- 1 kohm_cm = 1000 {ref}`schema:units:ohm_cm` +- 1 kohm_cm = 10 {ref}`schema:units:ohm_m` + +``` +```` + +(schema:units:litre)= +### litre + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:volume` +- Power of 10: -3 + + + +``` + +```{grid-item-card} Conversions + +- 1 litre = 1000 {ref}`schema:units:cm3` +- 1 litre = 0.001 {ref}`schema:units:m3` +- 1 litre = 1.00e+15 {ref}`schema:units:um3` + +``` +```` + +(schema:units:m__)= +### m + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:length` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 m = 100 {ref}`schema:units:cm` +- 1 m = 1.00e+06 {ref}`schema:units:um` + +``` +```` + +(schema:units:m2)= +### m2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:area` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 m2 = 10000 {ref}`schema:units:cm2` +- 1 m2 = 1.00e+12 {ref}`schema:units:um2` + +``` +```` + +(schema:units:m3)= +### m3 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:volume` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 m3 = 1.00e+06 {ref}`schema:units:cm3` +- 1 m3 = 1000 {ref}`schema:units:litre` +- 1 m3 = 1.00e+18 {ref}`schema:units:um3` + +``` +```` + +(schema:units:mA_per_cm2)= +### mA_per_cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:currentDensity` +- Power of 10: 1 + + + +``` + +```{grid-item-card} Conversions + +- 1 mA_per_cm2 = 10 {ref}`schema:units:A_per_m2` +- 1 mA_per_cm2 = 1000 {ref}`schema:units:uA_per_cm2` + +``` +```` + +(schema:units:mM)= +### mM + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:concentration` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 mM = 0.001 {ref}`schema:units:M` +- 1 mM = 1e-06 {ref}`schema:units:mol_per_cm3` +- 1 mM = 1 {ref}`schema:units:mol_per_m3` + +``` +```` + +(schema:units:mS)= +### mS + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance` +- Power of 10: -3 + + + +``` + +```{grid-item-card} Conversions + +- 1 mS = 0.001 {ref}`schema:units:S` +- 1 mS = 1.00e+06 {ref}`schema:units:nS` +- 1 mS = 1.00e+09 {ref}`schema:units:pS` +- 1 mS = 1000 {ref}`schema:units:uS` + +``` +```` + +(schema:units:mS_per_cm2)= +### mS_per_cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductanceDensity` +- Power of 10: 1 + + + +``` + +```{grid-item-card} Conversions + +- 1 mS_per_cm2 = 0.001 {ref}`schema:units:S_per_cm2` +- 1 mS_per_cm2 = 10 {ref}`schema:units:S_per_m2` +- 1 mS_per_cm2 = 1000 {ref}`schema:units:uS_per_cm2` + +``` +```` + +(schema:units:mV)= +### mV + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:voltage` +- Power of 10: -3 + + + +``` + +```{grid-item-card} Conversions + +- 1 mV = 0.001 {ref}`schema:units:V` + +``` +```` + +(schema:units:m_per_s)= +### m_per_s + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:permeability` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 m_per_s = 0.1 {ref}`schema:units:cm_per_ms` +- 1 m_per_s = 100 {ref}`schema:units:cm_per_s` +- 1 m_per_s = 1000 {ref}`schema:units:um_per_ms` + +``` +```` + +(schema:units:min)= +### min + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:time` +- Power of 10: 0 + + +- Scale: 60.0 + + +``` + +```{grid-item-card} Conversions + +- 1 min = 0.016667 {ref}`schema:units:hour` +- 1 min = 6.00e+04 {ref}`schema:units:ms__` +- 1 min = 60 {ref}`schema:units:s__` + +``` +```` + +(schema:units:mol)= +### mol + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:substance` +- Power of 10: 0 + + + +``` +```` + +(schema:units:mol_per_cm3)= +### mol_per_cm3 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:concentration` +- Power of 10: 6 + + + +``` + +```{grid-item-card} Conversions + +- 1 mol_per_cm3 = 1000 {ref}`schema:units:M` +- 1 mol_per_cm3 = 1.00e+06 {ref}`schema:units:mM` +- 1 mol_per_cm3 = 1.00e+06 {ref}`schema:units:mol_per_m3` + +``` +```` + +(schema:units:mol_per_cm_per_uA_per_ms)= +### mol_per_cm_per_uA_per_ms + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:rho_factor` +- Power of 10: 11 + + + +``` + +```{grid-item-card} Conversions + +- 1 mol_per_cm_per_uA_per_ms = 1.00e+11 {ref}`schema:units:mol_per_m_per_A_per_s` +- 1 mol_per_cm_per_uA_per_ms = 1000 {ref}`schema:units:umol_per_cm_per_nA_per_ms` + +``` +```` + +(schema:units:mol_per_m3)= +### mol_per_m3 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:concentration` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 mol_per_m3 = 0.001 {ref}`schema:units:M` +- 1 mol_per_m3 = 1 {ref}`schema:units:mM` +- 1 mol_per_m3 = 1e-06 {ref}`schema:units:mol_per_cm3` + +``` +```` + +(schema:units:mol_per_m_per_A_per_s)= +### mol_per_m_per_A_per_s + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:rho_factor` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 mol_per_m_per_A_per_s = 1e-11 {ref}`schema:units:mol_per_cm_per_uA_per_ms` +- 1 mol_per_m_per_A_per_s = 1e-08 {ref}`schema:units:umol_per_cm_per_nA_per_ms` + +``` +```` + +(schema:units:ms__)= +### ms + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:time` +- Power of 10: -3 + + + +``` + +```{grid-item-card} Conversions + +- 1 ms = 2.7778e-07 {ref}`schema:units:hour` +- 1 ms = 1.6667e-05 {ref}`schema:units:min` +- 1 ms = 0.001 {ref}`schema:units:s__` + +``` +```` + +(schema:units:nA)= +### nA + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:current` +- Power of 10: -9 + + + +``` + +```{grid-item-card} Conversions + +- 1 nA = 1e-09 {ref}`schema:units:A` +- 1 nA = 1000 {ref}`schema:units:pA` +- 1 nA = 0.001 {ref}`schema:units:uA` + +``` +```` + +(schema:units:nA_ms_per_amol)= +### nA_ms_per_amol + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:charge_per_mole` +- Power of 10: 6 + + + +``` + +```{grid-item-card} Conversions + +- 1 nA_ms_per_amol = 1.00e+06 {ref}`schema:units:C_per_mol` +- 1 nA_ms_per_amol = 1.00e+12 {ref}`schema:units:pC_per_umol` + +``` +```` + +(schema:units:nF)= +### nF + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:capacitance` +- Power of 10: -9 + + + +``` + +```{grid-item-card} Conversions + +- 1 nF = 1e-09 {ref}`schema:units:F` +- 1 nF = 1000 {ref}`schema:units:pF` +- 1 nF = 0.001 {ref}`schema:units:uF` + +``` +```` + +(schema:units:nS)= +### nS + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance` +- Power of 10: -9 + + + +``` + +```{grid-item-card} Conversions + +- 1 nS = 1e-09 {ref}`schema:units:S` +- 1 nS = 1e-06 {ref}`schema:units:mS` +- 1 nS = 1000 {ref}`schema:units:pS` +- 1 nS = 0.001 {ref}`schema:units:uS` + +``` +```` + +(schema:units:nS_per_mV)= +### nS_per_mV + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance_per_voltage` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 nS_per_mV = 1e-06 {ref}`schema:units:S_per_V` + +``` +```` + +(schema:units:ohm)= +### ohm + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:resistance` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 ohm = 1e-06 {ref}`schema:units:Mohm` +- 1 ohm = 0.001 {ref}`schema:units:kohm` + +``` +```` + +(schema:units:ohm_cm)= +### ohm_cm + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:resistivity` +- Power of 10: -2 + + + +``` + +```{grid-item-card} Conversions + +- 1 ohm_cm = 0.001 {ref}`schema:units:kohm_cm` +- 1 ohm_cm = 0.01 {ref}`schema:units:ohm_m` + +``` +```` + +(schema:units:ohm_m)= +### ohm_m + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:resistivity` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 ohm_m = 0.1 {ref}`schema:units:kohm_cm` +- 1 ohm_m = 100 {ref}`schema:units:ohm_cm` + +``` +```` + +(schema:units:pA)= +### pA + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:current` +- Power of 10: -12 + + + +``` + +```{grid-item-card} Conversions + +- 1 pA = 1e-12 {ref}`schema:units:A` +- 1 pA = 0.001 {ref}`schema:units:nA` +- 1 pA = 1e-06 {ref}`schema:units:uA` + +``` +```` + +(schema:units:pC_per_umol)= +### pC_per_umol + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:charge_per_mole` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 pC_per_umol = 1e-06 {ref}`schema:units:C_per_mol` +- 1 pC_per_umol = 1e-12 {ref}`schema:units:nA_ms_per_amol` + +``` +```` + +(schema:units:pF)= +### pF + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:capacitance` +- Power of 10: -12 + + + +``` + +```{grid-item-card} Conversions + +- 1 pF = 1e-12 {ref}`schema:units:F` +- 1 pF = 0.001 {ref}`schema:units:nF` +- 1 pF = 1e-06 {ref}`schema:units:uF` + +``` +```` + +(schema:units:pS)= +### pS + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance` +- Power of 10: -12 + + + +``` + +```{grid-item-card} Conversions + +- 1 pS = 1e-12 {ref}`schema:units:S` +- 1 pS = 1e-09 {ref}`schema:units:mS` +- 1 pS = 0.001 {ref}`schema:units:nS` +- 1 pS = 1e-06 {ref}`schema:units:uS` + +``` +```` + +(schema:units:per_V)= +### per_V + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_voltage` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 per_V = 0.001 {ref}`schema:units:per_mV` + +``` +```` + +(schema:units:per_hour)= +### per_hour + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_time` +- Power of 10: 0 + + +- Scale: 0.00027777777778 + + +``` + +```{grid-item-card} Conversions + +- 1 per_hour = 0.00027778 {ref}`schema:units:Hz` +- 1 per_hour = 0.016667 {ref}`schema:units:per_min` +- 1 per_hour = 2.7778e-07 {ref}`schema:units:per_ms` +- 1 per_hour = 0.00027778 {ref}`schema:units:per_s` + +``` +```` + +(schema:units:per_mV)= +### per_mV + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_voltage` +- Power of 10: 3 + + + +``` + +```{grid-item-card} Conversions + +- 1 per_mV = 1000 {ref}`schema:units:per_V` + +``` +```` + +(schema:units:per_min)= +### per_min + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_time` +- Power of 10: 0 + + +- Scale: 0.01666666667 + + +``` + +```{grid-item-card} Conversions + +- 1 per_min = 0.016667 {ref}`schema:units:Hz` +- 1 per_min = 60 {ref}`schema:units:per_hour` +- 1 per_min = 1.6667e-05 {ref}`schema:units:per_ms` +- 1 per_min = 0.016667 {ref}`schema:units:per_s` + +``` +```` + +(schema:units:per_ms)= +### per_ms + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_time` +- Power of 10: 3 + + + +``` + +```{grid-item-card} Conversions + +- 1 per_ms = 1000 {ref}`schema:units:Hz` +- 1 per_ms = 3.60e+06 {ref}`schema:units:per_hour` +- 1 per_ms = 6.00e+04 {ref}`schema:units:per_min` +- 1 per_ms = 1000 {ref}`schema:units:per_s` + +``` +```` + +(schema:units:per_s)= +### per_s + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:per_time` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 per_s = 1 {ref}`schema:units:Hz` +- 1 per_s = 3600 {ref}`schema:units:per_hour` +- 1 per_s = 60 {ref}`schema:units:per_min` +- 1 per_s = 0.001 {ref}`schema:units:per_ms` + +``` +```` + +(schema:units:s__)= +### s + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:time` +- Power of 10: 0 + + + +``` + +```{grid-item-card} Conversions + +- 1 s = 0.00027778 {ref}`schema:units:hour` +- 1 s = 0.016667 {ref}`schema:units:min` +- 1 s = 1000 {ref}`schema:units:ms__` + +``` +```` + +(schema:units:uA)= +### uA + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:current` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 uA = 1e-06 {ref}`schema:units:A` +- 1 uA = 1000 {ref}`schema:units:nA` +- 1 uA = 1.00e+06 {ref}`schema:units:pA` + +``` +```` + +(schema:units:uA_per_cm2)= +### uA_per_cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:currentDensity` +- Power of 10: -2 + + + +``` + +```{grid-item-card} Conversions + +- 1 uA_per_cm2 = 0.01 {ref}`schema:units:A_per_m2` +- 1 uA_per_cm2 = 0.001 {ref}`schema:units:mA_per_cm2` + +``` +```` + +(schema:units:uF)= +### uF + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:capacitance` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 uF = 1e-06 {ref}`schema:units:F` +- 1 uF = 1000 {ref}`schema:units:nF` +- 1 uF = 1.00e+06 {ref}`schema:units:pF` + +``` +```` + +(schema:units:uF_per_cm2)= +### uF_per_cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:specificCapacitance` +- Power of 10: -2 + + + +``` + +```{grid-item-card} Conversions + +- 1 uF_per_cm2 = 0.01 {ref}`schema:units:F_per_m2` + +``` +```` + +(schema:units:uS)= +### uS + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductance` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 uS = 1e-06 {ref}`schema:units:S` +- 1 uS = 0.001 {ref}`schema:units:mS` +- 1 uS = 1000 {ref}`schema:units:nS` +- 1 uS = 1.00e+06 {ref}`schema:units:pS` + +``` +```` + +(schema:units:uS_per_cm2)= +### uS_per_cm2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:conductanceDensity` +- Power of 10: -2 + + + +``` + +```{grid-item-card} Conversions + +- 1 uS_per_cm2 = 1e-06 {ref}`schema:units:S_per_cm2` +- 1 uS_per_cm2 = 0.01 {ref}`schema:units:S_per_m2` +- 1 uS_per_cm2 = 0.001 {ref}`schema:units:mS_per_cm2` + +``` +```` + +(schema:units:um)= +### um + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:length` +- Power of 10: -6 + + + +``` + +```{grid-item-card} Conversions + +- 1 um = 0.0001 {ref}`schema:units:cm` +- 1 um = 1e-06 {ref}`schema:units:m__` + +``` +```` + +(schema:units:um2)= +### um2 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:area` +- Power of 10: -12 + + + +``` + +```{grid-item-card} Conversions + +- 1 um2 = 1e-08 {ref}`schema:units:cm2` +- 1 um2 = 1e-12 {ref}`schema:units:m2` + +``` +```` + +(schema:units:um3)= +### um3 + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:volume` +- Power of 10: -18 + + + +``` + +```{grid-item-card} Conversions + +- 1 um3 = 1e-12 {ref}`schema:units:cm3` +- 1 um3 = 1e-15 {ref}`schema:units:litre` +- 1 um3 = 1e-18 {ref}`schema:units:m3` + +``` +```` + +(schema:units:um_per_ms)= +### um_per_ms + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:permeability` +- Power of 10: -3 + + + +``` + +```{grid-item-card} Conversions + +- 1 um_per_ms = 0.0001 {ref}`schema:units:cm_per_ms` +- 1 um_per_ms = 0.1 {ref}`schema:units:cm_per_s` +- 1 um_per_ms = 0.001 {ref}`schema:units:m_per_s` + +``` +```` + +(schema:units:umol_per_cm_per_nA_per_ms)= +### umol_per_cm_per_nA_per_ms + +````{grid} +:gutter: 2 + +```{grid-item-card} Summary +- Dimension: {ref}`schema:dimensions:rho_factor` +- Power of 10: 8 + + + +``` + +```{grid-item-card} Conversions + +- 1 umol_per_cm_per_nA_per_ms = 0.001 {ref}`schema:units:mol_per_cm_per_uA_per_ms` +- 1 umol_per_cm_per_nA_per_ms = 1.00e+08 {ref}`schema:units:mol_per_m_per_A_per_s` + +``` +```` + + diff --git a/_sources/Userdocs/Schemas/PyNN.md b/_sources/Userdocs/Schemas/PyNN.md new file mode 100644 index 00000000..43e45c94 --- /dev/null +++ b/_sources/Userdocs/Schemas/PyNN.md @@ -0,0 +1,2392 @@ + +(schema:pynn_)= +# PyNN + +**A number of ComponentType description of PyNN standard cells. All of the cells extend {ref}`schema:basepynncell`, and the synapses extend {ref}`schema:basepynnsynapse`.** + +--- + + +Original ComponentType definitions: [PyNN.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//PyNN.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:basepynncell)= + +## *basePyNNCell* + + + + +extends *{ref}`schema:basecellmembpot`* + + + +Base type of any PyNN standard cell model. Note: membrane potential **v** has dimensions voltage, but all other parameters are dimensionless. This is to facilitate translation to and from PyNN scripts in Python, where these parameters have implicit units, see http://neuralensemble.org/trac/PyNN/wiki/StandardModels. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ $Dimensionless +**i_offset**$ $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell $Dimensionless +**v_init**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MSEC** = 1ms$ $ {ref}`schema:dimensions:time` +**MVOLT** = 1mV$ $ {ref}`schema:dimensions:voltage` +**NFARAD** = 1nF$ $ {ref}`schema:dimensions:capacitance` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ $Direction: in +**spike_in_I**$ $Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` +````` + +(schema:basepynniafcell)= + +## *basePyNNIaFCell* + + + + +extends *{ref}`schema:basepynncell`* + + + +Base type of any PyNN standard integrate and fire model. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ $Dimensionless +**tau_refrac**$ $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ $Dimensionless +**v_rest**$ $Dimensionless +**v_thresh**$ $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` +````` + +(schema:basepynniafcondcell)= + +## *basePyNNIaFCondCell* + + + + +extends *{ref}`schema:basepynniafcell`* + + + +Base type of conductance based PyNN IaF cell models. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**e_rev_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell $Dimensionless +**e_rev_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` +````` + +(schema:if_curr_alpha)= + +## IF_curr_alpha + + + + +extends *{ref}`schema:basepynniafcell`* + + + +Leaky integrate and fire model with fixed threshold and alpha-function-shaped post-synaptic current. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = v_reset \* MVOLT +: **On Conditions** +:    IF t > lastSpikeTime + (tau_refrac*MSEC) THEN +:     TRANSITION to REGIME **integrating** + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > v_thresh * MVOLT THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (MVOLT * ((i_offset/cm) + ((v_rest - (v/MVOLT)) / tau_m))/MSEC) + (iSyn / (cm * NFARAD)) +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IF_curr_alpha + +variable = IF_curr_alpha( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + tau_m: 'a float (required)' = None, + tau_refrac: 'a float (required)' = None, + v_reset: 'a float (required)' = None, + v_rest: 'a float (required)' = None, + v_thresh: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:if_curr_exp)= + +## IF_curr_exp + + + + +extends *{ref}`schema:basepynniafcell`* + + + +Leaky integrate and fire model with fixed threshold and decaying-exponential post-synaptic current. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = v_reset \* MVOLT +: **On Conditions** +:    IF t > lastSpikeTime + (tau_refrac*MSEC) THEN +:     TRANSITION to REGIME **integrating** + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > v_thresh * MVOLT THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (MVOLT * (((i_offset)/cm) + ((v_rest - (v/MVOLT)) / tau_m))/MSEC) + (iSyn / (cm * NFARAD)) +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IF_curr_exp + +variable = IF_curr_exp( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + tau_m: 'a float (required)' = None, + tau_refrac: 'a float (required)' = None, + v_reset: 'a float (required)' = None, + v_rest: 'a float (required)' = None, + v_thresh: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:if_cond_alpha)= + +## IF_cond_alpha + + + + +extends *{ref}`schema:basepynniafcondcell`* + + + +Leaky integrate and fire model with fixed threshold and alpha-function-shaped post-synaptic conductance. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**e_rev_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**e_rev_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = v_reset \* MVOLT +: **On Conditions** +:    IF t > lastSpikeTime + (tau_refrac*MSEC) THEN +:     TRANSITION to REGIME **integrating** + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > v_thresh * MVOLT THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (MVOLT * (((i_offset) / cm) + ((v_rest - (v / MVOLT)) / tau_m)) / MSEC) + (iSyn / (cm * NFARAD)) +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IF_cond_alpha + +variable = IF_cond_alpha( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + tau_m: 'a float (required)' = None, + tau_refrac: 'a float (required)' = None, + v_reset: 'a float (required)' = None, + v_rest: 'a float (required)' = None, + v_thresh: 'a float (required)' = None, + e_rev_E: 'a float (required)' = None, + e_rev_I: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:if_cond_exp)= + +## IF_cond_exp + + + + +extends *{ref}`schema:basepynniafcondcell`* + + + +Leaky integrate and fire model with fixed threshold and exponentially-decaying post-synaptic conductance. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**e_rev_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**e_rev_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + + + + + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = v_reset \* MVOLT +: **On Conditions** +:    IF t > lastSpikeTime + (tau_refrac*MSEC) THEN +:     TRANSITION to REGIME **integrating** + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > v_thresh * MVOLT THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (MVOLT * (((i_offset)/cm) + ((v_rest - (v / MVOLT)) / tau_m)) / MSEC) + (iSyn / (cm * NFARAD)) +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import IF_cond_exp + +variable = IF_cond_exp( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + tau_m: 'a float (required)' = None, + tau_refrac: 'a float (required)' = None, + v_reset: 'a float (required)' = None, + v_rest: 'a float (required)' = None, + v_thresh: 'a float (required)' = None, + e_rev_E: 'a float (required)' = None, + e_rev_I: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:eif_cond_exp_isfa_ista)= + +## EIF_cond_exp_isfa_ista + + + + +extends *{ref}`schema:basepynniafcondcell`* + + + +Adaptive exponential integrate and fire neuron according to Brette R and Gerstner W ( 2005 ) with exponentially-decaying post-synaptic conductance. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**a**$ $Dimensionless +**b**$ $Dimensionless +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**delta_T**$ $Dimensionless +**e_rev_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**e_rev_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_w**$ $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_spike**$ $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**eif_threshold**$ $Dimensionless +``` +   **eif_threshold** = v_spike * H(delta_T-1e-12) + v_thresh * H(-1*delta_T+1e-9) + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` +**w**$ $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **w**: Dimensionless  (exposed as **w**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT +: **w** = 0 + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + + + + +**Conditional Derived Variables** + +: IF delta_T > 0 THEN +:   **delta_I** = delta_T \* exp(((v / MVOLT) - v_thresh) / delta_T) +: IF delta_T = 0 THEN +:   **delta_I** = 0 + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = v_reset \* MVOLT +:    **w** = w+b +: **On Conditions** +:    IF t > lastSpikeTime + (tau_refrac*MSEC) THEN +:     TRANSITION to REGIME **integrating** +: **Time Derivatives** +:    d **w** /dt = (1 / tau_w) * (a * ((v / MVOLT) - v_rest) - w) / MSEC + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > eif_threshold * MVOLT THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (MVOLT * ((-1 * ((v / MVOLT) - v_rest) + delta_I) / tau_m + (i_offset - w) / cm) / MSEC) + (iSyn / (cm * NFARAD)) +:    d **w** /dt = (1 / tau_w) * (a * ((v / MVOLT) - v_rest) - w) / MSEC +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import EIF_cond_exp_isfa_ista + +variable = EIF_cond_exp_isfa_ista( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + tau_m: 'a float (required)' = None, + tau_refrac: 'a float (required)' = None, + v_reset: 'a float (required)' = None, + v_rest: 'a float (required)' = None, + v_thresh: 'a float (required)' = None, + e_rev_E: 'a float (required)' = None, + e_rev_I: 'a float (required)' = None, + a: 'a float (required)' = None, + b: 'a float (required)' = None, + delta_T: 'a float (required)' = None, + tau_w: 'a float (required)' = None, + v_spike: 'a float (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:eif_cond_alpha_isfa_ista)= + +## EIF_cond_alpha_isfa_ista + + + + +extends *{ref}`schema:basepynniafcondcell`* + + + +Adaptive exponential integrate and fire neuron according to Brette R and Gerstner W ( 2005 ) with alpha-function-shaped post-synaptic conductance. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**a**$ $Dimensionless +**b**$ $Dimensionless +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**delta_T**$ $Dimensionless +**e_rev_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**e_rev_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynniafcondcell`)* $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_m**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_refrac**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_w**$ $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_reset**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_rest**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless +**v_spike**$ $Dimensionless +**v_thresh**$ *(from {ref}`schema:basepynniafcell`)* $Dimensionless + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**eif_threshold**$ $Dimensionless +``` +   **eif_threshold** = v_spike * H(delta_T-1e-12) + v_thresh * H(-1*delta_T+1e-9) + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` +**w**$ $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **w**: Dimensionless  (exposed as **w**) +: **lastSpikeTime**: {ref}`schema:dimensions:time` + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT +: **w** = 0 + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + + + + +**Conditional Derived Variables** + +: IF delta_T > 0 THEN +:   **delta_I** = delta_T \* exp(((v / MVOLT) - v_thresh) / delta_T) +: IF delta_T = 0 THEN +:   **delta_I** = 0 + + + +**Regime: refractory (initial)** +: **On Entry** +:    **lastSpikeTime** = t +:    **v** = v_reset \* MVOLT +:    **w** = w + b +: **On Conditions** +:    IF t > lastSpikeTime + (tau_refrac * MSEC) THEN +:     TRANSITION to REGIME **integrating** +: **Time Derivatives** +:    d **w** /dt = (1 / tau_w) * (a * ((v / MVOLT) - v_rest) - w) / MSEC + +**Regime: integrating (initial)** +: **On Conditions** +:    IF v > eif_threshold * MVOLT THEN +:     EVENT OUT on port: **spike** +:     TRANSITION to REGIME **refractory** +: **Time Derivatives** +:    d **v** /dt = (MVOLT * ((-1 * ( (v / MVOLT) - v_rest) + delta_I) / tau_m + (i_offset - w) / cm) / MSEC) + (iSyn / (cm * NFARAD)) +:    d **w** /dt = (1/ tau_w) * (a*((v/MVOLT)-v_rest) - w) /MSEC +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import EIF_cond_alpha_isfa_ista + +variable = EIF_cond_alpha_isfa_ista( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + tau_m: 'a float (required)' = None, + tau_refrac: 'a float (required)' = None, + v_reset: 'a float (required)' = None, + v_rest: 'a float (required)' = None, + v_thresh: 'a float (required)' = None, + e_rev_E: 'a float (required)' = None, + e_rev_I: 'a float (required)' = None, + a: 'a float (required)' = None, + b: 'a float (required)' = None, + delta_T: 'a float (required)' = None, + tau_w: 'a float (required)' = None, + v_spike: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:hh_cond_exp)= + +## HH_cond_exp + + + + +extends *{ref}`schema:basepynncell`* + + + +Single-compartment Hodgkin-Huxley-type neuron with transient sodium and delayed-rectifier potassium currents using the ion channel models from Traub. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**cm**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**e_rev_E**$ $Dimensionless +**e_rev_I**$ $Dimensionless +**e_rev_K**$ $Dimensionless +**e_rev_Na**$ $Dimensionless +**e_rev_leak**$ $Dimensionless +**g_leak**$ $Dimensionless +**gbar_K**$ $Dimensionless +**gbar_Na**$ $Dimensionless +**i_offset**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_E**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**tau_syn_I**$ This parameter is never used in the NeuroML2 description of this cell! Any synapse producing a current can be placed on this cell *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_init**$ *(from {ref}`schema:basepynncell`)* $Dimensionless +**v_offset**$ $Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**h**$ $Dimensionless +**iSyn**$ *(from {ref}`schema:basepynncell`)* ${ref}`schema:dimensions:current` +**m**$ $Dimensionless +**n**$ $Dimensionless +**v**$ Membrane potential *(from {ref}`schema:basecellmembpot`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**spike**$ Spike event *(from {ref}`schema:basespikingcell`)*$Direction: out +**spike_in_E**$ *(from {ref}`schema:basepynncell`)*$Direction: in +**spike_in_I**$ *(from {ref}`schema:basepynncell`)*$Direction: in + +``` +```` + +````{tab-item} Attachments +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapses**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **v**: {ref}`schema:dimensions:voltage`  (exposed as **v**) +: **m**: Dimensionless  (exposed as **m**) +: **h**: Dimensionless  (exposed as **h**) +: **n**: Dimensionless  (exposed as **n**) + + + + + + + + + +**On Start** +: **v** = v_init * MVOLT + + + + + +**Derived Variables** + : **iSyn** = synapses[*]->i(reduce method: add) (exposed as **iSyn**) + : **iLeak** = g_leak * (e_rev_leak - (v / MVOLT)) + : **iNa** = gbar_Na * (m * m * m) * h * (e_rev_Na - (v / MVOLT)) + : **iK** = gbar_K * (n * n * n * n) * (e_rev_K - (v / MVOLT)) + : **iMemb** = iLeak + iNa + iK + i_offset + : **alpham** = 0.32 * (13 - (v / MVOLT) + v_offset) / (exp((13 - (v / MVOLT) + v_offset) / 4.0) - 1) + : **betam** = 0.28 * ((v / MVOLT) - v_offset - 40) / (exp(((v / MVOLT) - v_offset - 40) / 5.0) - 1) + : **alphah** = 0.128 * exp((17 - (v / MVOLT) + v_offset) / 18.0) + : **betah** = 4.0 / (1 + exp((40 - (v / MVOLT) + v_offset) / 5)) + : **alphan** = 0.032 * (15 - (v / MVOLT) + v_offset) / (exp((15 - (v / MVOLT) + v_offset) / 5) - 1) + : **betan** = 0.5 * exp((10 - (v / MVOLT) + v_offset) / 40) + + + + + + +**Time Derivatives** + : d **v** /dt = (MVOLT * (iMemb / cm) / MSEC) + (iSyn / (cm * NFARAD)) + : d **m** /dt = (alpham * (1 - m) - betam * m) / MSEC + : d **h** /dt = (alphah * (1 - h) - betah * h) / MSEC + : d **n** /dt = (alphan * (1 - n) - betan * n) / MSEC + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import HH_cond_exp + +variable = HH_cond_exp( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + cm: 'a float (required)' = None, + i_offset: 'a float (required)' = None, + tau_syn_E: 'a float (required)' = None, + tau_syn_I: 'a float (required)' = None, + v_init: 'a float (required)' = None, + v_offset: 'a float (required)' = None, + e_rev_E: 'a float (required)' = None, + e_rev_I: 'a float (required)' = None, + e_rev_K: 'a float (required)' = None, + e_rev_Na: 'a float (required)' = None, + e_rev_leak: 'a float (required)' = None, + g_leak: 'a float (required)' = None, + gbar_K: 'a float (required)' = None, + gbar_Na: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:basepynnsynapse)= + +## *basePynnSynapse* + + + + +extends *{ref}`schema:basevoltagedepsynapse`* + + + +Base type for all PyNN synapses. Note, the current **I** produced is dimensionless, but it requires a membrane potential **v** with dimension voltage. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tau_syn**$ $Dimensionless + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**MSEC** = 1ms$ $ {ref}`schema:dimensions:time` +**MVOLT** = 1mV$ $ {ref}`schema:dimensions:voltage` +**NAMP** = 1nA$ $ {ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BasePynnSynapse + +variable = BasePynnSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + tau_syn: 'a float (required)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:expcondsynapse)= + +## expCondSynapse + + + + +extends *{ref}`schema:basepynnsynapse`* + + + +Conductance based synapse with instantaneous rise and single exponential decay ( with time constant tau_syn ). + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**e_rev**$ $Dimensionless +**tau_syn**$ *(from {ref}`schema:basepynnsynapse`)* $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ $Dimensionless +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **g**: Dimensionless  (exposed as **g**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** +:    **g** = g+weight + + + + + +**Derived Variables** + : **i** = g * (e_rev - (v/MVOLT)) * NAMP (exposed as **i**) + + + + + + +**Time Derivatives** + : d **g** /dt = -g / (tau_syn*MSEC) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ExpCondSynapse + +variable = ExpCondSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + tau_syn: 'a float (required)' = None, + e_rev: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:expcurrsynapse)= + +## expCurrSynapse + + + + +extends *{ref}`schema:basepynnsynapse`* + + + +Current based synapse with instantaneous rise and single exponential decay ( with time constant tau_syn ). + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tau_syn**$ *(from {ref}`schema:basepynnsynapse`)* $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **I**: Dimensionless + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** +:    **I** = I + weight + + + + + +**Derived Variables** + : **i** = I * NAMP (exposed as **i**) + + + + + + +**Time Derivatives** + : d **I** /dt = -I / (tau_syn*MSEC) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ExpCurrSynapse + +variable = ExpCurrSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + tau_syn: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:alphacondsynapse)= + +## alphaCondSynapse + + + + +extends *{ref}`schema:basepynnsynapse`* + + + +Alpha synapse: rise time and decay time are both tau_syn. Conductance based synapse. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**e_rev**$ $Dimensionless +**tau_syn**$ *(from {ref}`schema:basepynnsynapse`)* $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**A**$ $Dimensionless +**g**$ $Dimensionless +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **g**: Dimensionless  (exposed as **g**) +: **A**: Dimensionless  (exposed as **A**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + weight + + + + + +**Derived Variables** + : **i** = g * (e_rev - (v/MVOLT)) * NAMP (exposed as **i**) + + + + + + +**Time Derivatives** + : d **g** /dt = (2.7182818*A - g)/(tau_syn*MSEC) + : d **A** /dt = -A /(tau_syn*MSEC) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import AlphaCondSynapse + +variable = AlphaCondSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + tau_syn: 'a float (required)' = None, + e_rev: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:alphacurrsynapse)= + +## alphaCurrSynapse + + + + +extends *{ref}`schema:basepynnsynapse`* + + + +Alpha synapse: rise time and decay time are both tau_syn. Current based synapse. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**tau_syn**$ *(from {ref}`schema:basepynnsynapse`)* $Dimensionless + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**A**$ ${ref}`schema:dimensions:current` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **I**: Dimensionless +: **A**: Dimensionless  (exposed as **A**) + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + weight + + + + + +**Derived Variables** + : **i** = I * NAMP (exposed as **i**) + + + + + + +**Time Derivatives** + : d **I** /dt = (2.7182818*A - I)/(tau_syn*MSEC) + : d **A** /dt = -A /(tau_syn*MSEC) + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import AlphaCurrSynapse + +variable = AlphaCurrSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + tau_syn: 'a float (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:spikesourcepoisson)= + +## SpikeSourcePoisson + + + + +extends *{ref}`schema:basespikesource`* + + + +Spike source, generating spikes according to a Poisson process. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**duration**$ ${ref}`schema:dimensions:time` +**rate**$ ${ref}`schema:dimensions:per_time` +**start**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**LONG_TIME** = 1e9hour$ $ {ref}`schema:dimensions:time` +**SMALL_TIME** = 1e-9ms$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**end**$ ${ref}`schema:dimensions:time` +``` +   **end** = start + duration + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**isi**$ ${ref}`schema:dimensions:time` +**tnextIdeal**$ ${ref}`schema:dimensions:time` +**tnextUsed**$ ${ref}`schema:dimensions:time` +**tsince**$ Time since the last spike was emitted *(from {ref}`schema:basespikesource`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ $Direction: in +**spike**$ Port on which spikes are emitted *(from {ref}`schema:basespikesource`)*$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) +: **tnextIdeal**: {ref}`schema:dimensions:time`  (exposed as **tnextIdeal**) +: **tnextUsed**: {ref}`schema:dimensions:time`  (exposed as **tnextUsed**) +: **isi**: {ref}`schema:dimensions:time`  (exposed as **isi**) + + + + + + + + + +**On Start** +: **isi** = start - log(random(1))/rate +: **tsince** = 0 +: **tnextIdeal** = isi + H(((isi) - (start+duration))/duration)*LONG_TIME +: **tnextUsed** = tnextIdeal + + + +**On Conditions** + +: IF t > tnextUsed THEN +:    **isi** = -1 * log(random(1))/rate +:    **tnextIdeal** = (tnextIdeal+isi) + H(((tnextIdeal+isi) - (start+duration))/duration)*LONG_TIME +:    **tnextUsed** = tnextIdeal*H( (tnextIdeal-t)/t ) + (t+SMALL_TIME)*H( (t-tnextIdeal)/t ) +:    **tsince** = 0 +:    EVENT OUT on port: **spike** + + + + + + + + +**Time Derivatives** + : d **tsince** /dt = 1 + : d **tnextUsed** /dt = 0 + : d **tnextIdeal** /dt = 0 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SpikeSourcePoisson + +variable = SpikeSourcePoisson( + id: 'a NonNegativeInteger (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + start: 'a Nml2Quantity_time (required)' = None, + duration: 'a Nml2Quantity_time (required)' = None, + rate: 'a Nml2Quantity_pertime (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` diff --git a/_sources/Userdocs/Schemas/Simulation.md b/_sources/Userdocs/Schemas/Simulation.md new file mode 100644 index 00000000..af78acc2 --- /dev/null +++ b/_sources/Userdocs/Schemas/Simulation.md @@ -0,0 +1,332 @@ + +(schema:simulation_)= +# Simulation + +**Specification of the LEMS Simulation element which is normally used to define simulations of NeuroML2 files. Note: not actually part of NeuroML v2, but this is required by much of the NeuroML toolchain for defining Simulations ( which NeuroML model to use and how long to run for ), as well as what to {ref}`schema:display` and what to save in {ref}`schema:outputfile`s.** + +--- + + +Original ComponentType definitions: [Simulation.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//Simulation.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:simulation)= + +## Simulation + + + + +The main element in a LEMS Simulation file. Defines the **length** of simulation, the timestep ( dt ) **step** and an optional **seed** to use for stochastic elements, as well as {ref}`schema:display`s, {ref}`schema:outputfile`s and {ref}`schema:eventoutputfile`s to record. Specifies a **target** component to run, usually the id of a {ref}`schema:network`. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**length**$ Duration of the simulation run ${ref}`schema:dimensions:time` +**step**$ Time step (dt) to use in the simulation ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**seed**$ The seed to use in the random number generator for stochastic entities + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**target**$ $ {ref}`schema:component` + +``` +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**metas**$ $ {ref}`schema:meta` +**displays**$ $ {ref}`schema:display` +**outputs**$ $ {ref}`schema:outputfile` +**events**$ $ {ref}`schema:eventoutputfile` + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **t**: {ref}`schema:dimensions:time` + + + + + + + + + + +```` +````` + +(schema:display)= + +## Display + + + + +Details of a display to generate ( usually a set of traces given by {ref}`schema:line`s in a newly opened window ) on completion of the simulation. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**timeScale**$ A scaling of the time axis, e.g. 1ms means display in milliseconds. Note: all quantities are recorded in SI units ${ref}`schema:dimensions:time` +**xmax**$ The maximum value on the x axis (i.e time variable) of the display $Dimensionless +**xmin**$ The minimum value on the x axis (i.e time variable) of the display $Dimensionless +**ymax**$ The maximum value on the x axis of the display $Dimensionless +**ymin**$ The minimum value on the y axis of the display $Dimensionless + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**title**$ The title of the display, e.g. to use for the window + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**lines**$ $ {ref}`schema:line` + +``` +```` +````` + +(schema:line)= + +## Line + + + + +Specification of a single time varying **quantity** to plot on the {ref}`schema:display`. Note that all quantities are handled internally in LEMS in SI units, and so a **scale** should be used if it is to be displayed in other units. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**scale**$ A scaling factor to DIVIDE the quantity by. Can be dimensional, so using scale=1mV means a value of -0.07V is displayed as -70. Alternatively, scale=0.001 would achieve the same thing. ${ref}`schema:dimensions:*` +**timeScale**$ An optional scaling of the time axis, e.g. 1ms means display in milliseconds. Note: if present, this overrides timeScale from _Display_ ${ref}`schema:dimensions:*` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**color**$ A hex string for the color to display the trace for this quantity, e.g. #aa33ff + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**quantity**$ Path to the quantity to display, see see https://docs.neuroml.org/Userdocs/Paths.html. + +```` +````` + +(schema:outputfile)= + +## OutputFile + + + + +A file in which to save recorded values from the simulation. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**path**$ Optional path to the directory in which to store the file +**fileName**$ Name of the file to generate. Can include a relative path (from the LEMS Simulation file location). + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**outputColumn**$ $ {ref}`schema:outputcolumn` + +``` +```` +````` + +(schema:outputcolumn)= + +## OutputColumn + + + + +Specification of a single time varying **quantity** to record during the simulation. Note that all quantities are handled internally in LEMS in SI units, and so the value for the quantity in the file ( as well as time ) will be in SI units. + + +`````{tab-set} +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**quantity**$ Path to the quantity to save, see see https://docs.neuroml.org/Userdocs/Paths.html. Note that all quantities are saved in SI units. + +```` +````` + +(schema:eventoutputfile)= + +## EventOutputFile + + + + +A file in which to save event information ( e.g. spikes from cells in a population ) in a specified **format**. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**path**$ Optional path to the directory in which to store the file +**fileName**$ Name of the file to generate. Can include a relative path (from the LEMS Simulation file location). +**format**$ Takes values TIME_ID or ID_TIME, depending on the preferred order of the time or event id (from _EventSelection_) in each row of the file + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**eventSelection**$ $ {ref}`schema:eventselection` + +``` +```` +````` + +(schema:eventselection)= + +## EventSelection + + + + +A specific source of events with an associated **id,** which will be recorded inside the file specified in the parent {ref}`schema:eventoutputfile`. The attribute **select** should point to a cell inside a {ref}`schema:population` ( e.g. hhpop[0], see https://docs.neuroml.org/Userdocs/Paths.html ), and the **eventPort** specifies the port for the emitted events, which usually has id: spike. Note: the **id** used on this element ( and appearing in the file alongside the event time ) can be different from the id/index of the cell in the population. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**eventPort**$ The port on the cell which generates the events, usually: spike + +```` + +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**select**$ The cell which will be emitting the events + +```` +````` + +(schema:meta)= + +## Meta + + + + +Metadata to add to simulation. + + +`````{tab-set} +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**for**$ Simulator name +**method**$ Integration method to use +**abs_tolerance**$ Absolute tolerance for NEURON's cvode method +**rel_tolerance**$ Relative tolerance for NEURON's cvode method + +```` +````` diff --git a/_sources/Userdocs/Schemas/Synapses.md b/_sources/Userdocs/Schemas/Synapses.md new file mode 100644 index 00000000..e66866ed --- /dev/null +++ b/_sources/Userdocs/Schemas/Synapses.md @@ -0,0 +1,2813 @@ + +(schema:synapses_)= +# Synapses + +**A number of synaptic ComponentTypes for use in NeuroML 2 documents, e.g. {ref}`schema:exponesynapse`, {ref}`schema:exptwosynapse`, {ref}`schema:blockingplasticsynapse`. These extend the {ref}`schema:basesynapse` ComponentType. Also defined continuously transmitting synapses, e.g. {ref}`schema:gapjunction` and {ref}`schema:gradedsynapse`.** + +--- + + +Original ComponentType definitions: [Synapses.xml](https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes//Synapses.xml). +Schema against which NeuroML based on these should be valid: [NeuroML_v2.3.xsd](https://github.com/NeuroML/NeuroML2/tree/master/Schemas/NeuroML2/NeuroML_v2.3.xsd). +Generated on 05/12/23 from [this](https://github.com/NeuroML/NeuroML2/commit/352244cff605cb1ba24fa7c11757dc818fe90fd2) commit. +Please file any issues or questions at the [issue tracker here](https://github.com/NeuroML/NeuroML2/issues). + +--- + +(schema:basesynapse)= + +## *baseSynapse* + + + + +extends *{ref}`schema:basepointcurrent`* + + + +Base type for all synapses, i.e. ComponentTypes which produce a current ( dimension current ) and change Dynamics in response to an incoming event. + + +[Bioportal entry for Computational Neuroscience Ontology related to baseSynapse.](https://bioportal.bioontology.org/ontologies/CNO/?p=classes&conceptid=cno_0000009) + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ $Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseSynapse + +variable = BaseSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:basevoltagedepsynapse)= + +## *baseVoltageDepSynapse* + + + + +extends *{ref}`schema:basesynapse`* + + + +Base type for synapses with a dependence on membrane potential. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseVoltageDepSynapse + +variable = BaseVoltageDepSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:basesynapsedl)= + +## *baseSynapseDL* + + + + +extends *{ref}`schema:basevoltagedeppointcurrentdl`* + + + +Base type for all synapses, i.e. ComponentTypes which produce a dimensionless current and change Dynamics in response to an incoming event. + + +[Bioportal entry for Computational Neuroscience Ontology related to baseSynapseDL.](https://bioportal.bioontology.org/ontologies/CNO/?p=classes&conceptid=cno_0000009) + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**I**$ The total (time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrentdl`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**V**$ The current may vary with the dimensionless voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedeppointcurrentdl`)* $Dimensionless + +``` +```` +````` + +(schema:basecurrentbasedsynapse)= + +## *baseCurrentBasedSynapse* + + + + +extends *{ref}`schema:basesynapse`* + + + +Synapse model which produces a synaptic current. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseCurrentBasedSynapse + +variable = BaseCurrentBasedSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:alphacurrentsynapse)= + +## alphaCurrentSynapse + + + + +extends *{ref}`schema:basecurrentbasedsynapse`* + + + +Alpha current synapse: rise time and decay time are both **tau.**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**ibase**$ Baseline current increase after receiving a spike ${ref}`schema:dimensions:current` +**tau**$ Time course for rise and decay ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **I**: {ref}`schema:dimensions:current` +: **J**: {ref}`schema:dimensions:current` + + + + + + + + + +**On Start** +: **I** = 0 +: **J** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **J** = J + weight * ibase + + + + + +**Derived Variables** + : **i** = I (exposed as **i**) + + + + + + +**Time Derivatives** + : d **I** /dt = (2.7182818284590451*J - I)/tau + : d **J** /dt = -J/tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import AlphaCurrentSynapse + +variable = AlphaCurrentSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + tau: 'a Nml2Quantity_time (required)' = None, + ibase: 'a Nml2Quantity_current (required)' = None, +) +``` +```` +````` + +(schema:baseconductancebasedsynapse)= + +## *baseConductanceBasedSynapse* + + + + +extends *{ref}`schema:basevoltagedepsynapse`* + + + +Synapse model which exposes a conductance **g** in addition to producing a current. Not necessarily ohmic!! + + +[Bioportal entry for Computational Neuroscience Ontology related to baseConductanceBasedSynapse.](https://bioportal.bioontology.org/ontologies/CNO/?p=classes&conceptid=cno_0000027) + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse ${ref}`schema:dimensions:voltage` +**gbase**$ Baseline conductance, generally the maximum conductance following a single spike ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseConductanceBasedSynapse + +variable = BaseConductanceBasedSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:baseconductancebasedsynapsetwo)= + +## *baseConductanceBasedSynapseTwo* + + + + +extends *{ref}`schema:basevoltagedepsynapse`* + + + +Synapse model suited for a sum of two expTwoSynapses which exposes a conductance **g** in addition to producing a current. Not necessarily ohmic!! + + +[Bioportal entry for Computational Neuroscience Ontology related to baseConductanceBasedSynapseTwo.](https://bioportal.bioontology.org/ontologies/CNO/?p=classes&conceptid=cno_0000027) + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse ${ref}`schema:dimensions:voltage` +**gbase1**$ Baseline conductance 1 ${ref}`schema:dimensions:conductance` +**gbase2**$ Baseline conductance 2 ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BaseConductanceBasedSynapseTwo + +variable = BaseConductanceBasedSynapseTwo( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase1: 'a Nml2Quantity_conductance (required)' = None, + gbase2: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + extensiontype_=None, +) +``` +```` +````` + +(schema:exponesynapse)= + +## expOneSynapse + + + + +extends *{ref}`schema:baseconductancebasedsynapse`* + + + +Ohmic synapse model whose conductance rises instantaneously by ( **gbase** * **weight** ) on receiving an event, and which decays exponentially to zero with time course **tauDecay**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:voltage` +**gbase**$ Baseline conductance, generally the maximum conductance following a single spike *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**tauDecay**$ Time course of decay ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **g**: {ref}`schema:dimensions:conductance`  (exposed as **g**) + + + + + + + + + +**On Start** +: **g** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **g** = g + (weight * gbase) + + + + + +**Derived Variables** + : **i** = g * (erev - v) (exposed as **i**) + + + + + + +**Time Derivatives** + : d **g** /dt = -g / tauDecay + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ExpOneSynapse + +variable = ExpOneSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + tau_decay: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:alphasynapse)= + +## alphaSynapse + + + + +extends *{ref}`schema:baseconductancebasedsynapse`* + + + +Ohmic synapse model where rise time and decay time are both **tau.** Max conductance reached during this time ( assuming zero conductance before ) is **gbase** * **weight.**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:voltage` +**gbase**$ Baseline conductance, generally the maximum conductance following a single spike *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**tau**$ Time course of rise/decay ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **g**: {ref}`schema:dimensions:conductance`  (exposed as **g**) +: **A**: {ref}`schema:dimensions:conductance` + + + + + + + + + +**On Start** +: **g** = 0 +: **A** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + (gbase*weight) + + + + + +**Derived Variables** + : **i** = g * (erev - v) (exposed as **i**) + + + + + + +**Time Derivatives** + : d **g** /dt = (2.7182818284590451 * A - g)/tau + : d **A** /dt = -A / tau + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import AlphaSynapse + +variable = AlphaSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + tau: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + An alpha synapse with time for rise equal to decay. + +``` +```` +````` + +(schema:exptwosynapse)= + +## expTwoSynapse + + + + +extends *{ref}`schema:baseconductancebasedsynapse`* + + + +Ohmic synapse model whose conductance waveform on receiving an event has a rise time of **tauRise** and a decay time of **tauDecay.** Max conductance reached during this time ( assuming zero conductance before ) is **gbase** * **weight.**. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:voltage` +**gbase**$ Baseline conductance, generally the maximum conductance following a single spike *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**tauDecay**$ ${ref}`schema:dimensions:time` +**tauRise**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**peakTime**$ ${ref}`schema:dimensions:time` +``` +   **peakTime** = log(tauDecay / tauRise) * (tauRise * tauDecay)/(tauDecay - tauRise) +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**waveformFactor**$ $Dimensionless +``` +   **waveformFactor** = 1 / (-exp(-peakTime / tauRise) + exp(-peakTime / tauDecay)) + +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **A**: Dimensionless +: **B**: Dimensionless + + + + + + + + + +**On Start** +: **A** = 0 +: **B** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + (weight * waveformFactor) +:    **B** = B + (weight * waveformFactor) + + + + + +**Derived Variables** + : **g** = gbase * (B - A) (exposed as **g**) + : **i** = g * (erev - v) (exposed as **i**) + + + + + + +**Time Derivatives** + : d **A** /dt = -A / tauRise + : d **B** /dt = -B / tauDecay + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ExpTwoSynapse + +variable = ExpTwoSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + tau_decay: 'a Nml2Quantity_time (required)' = None, + tau_rise: 'a Nml2Quantity_time (required)' = None, + extensiontype_=None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:expthreesynapse)= + +## expThreeSynapse + + + + +extends *{ref}`schema:baseconductancebasedsynapsetwo`* + + + +Ohmic synapse similar to expTwoSynapse but consisting of two components that can differ in decay times and max conductances but share the same rise time. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse *(from {ref}`schema:baseconductancebasedsynapsetwo`)* ${ref}`schema:dimensions:voltage` +**gbase1**$ Baseline conductance 1 *(from {ref}`schema:baseconductancebasedsynapsetwo`)* ${ref}`schema:dimensions:conductance` +**gbase2**$ Baseline conductance 2 *(from {ref}`schema:baseconductancebasedsynapsetwo`)* ${ref}`schema:dimensions:conductance` +**tauDecay1**$ ${ref}`schema:dimensions:time` +**tauDecay2**$ ${ref}`schema:dimensions:time` +**tauRise**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**peakTime1**$ ${ref}`schema:dimensions:time` +``` +   **peakTime1** = log(tauDecay1 / tauRise) * (tauRise * tauDecay1)/(tauDecay1 - tauRise) +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**peakTime2**$ ${ref}`schema:dimensions:time` +``` +   **peakTime2** = log(tauDecay2 / tauRise) * (tauRise * tauDecay2)/(tauDecay2 - tauRise) +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**waveformFactor1**$ $Dimensionless +``` +   **waveformFactor1** = 1 / (-exp(-peakTime1 / tauRise) + exp(-peakTime1 / tauDecay1)) +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**waveformFactor2**$ $Dimensionless +``` +   **waveformFactor2** = 1 / (-exp(-peakTime2 / tauRise) + exp(-peakTime2 / tauDecay2)) + +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse *(from {ref}`schema:baseconductancebasedsynapsetwo`)* ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **A**: Dimensionless +: **B**: Dimensionless +: **C**: Dimensionless + + + + + + + + + +**On Start** +: **A** = 0 +: **B** = 0 +: **C** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + (gbase1*weight * waveformFactor1 + gbase2*weight*waveformFactor2 )/(gbase1+gbase2) +:    **B** = B + (weight * waveformFactor1) +:    **C** = C + (weight * waveformFactor2) + + + + + +**Derived Variables** + : **g** = gbase1*(B - A) + gbase2*(C-A) (exposed as **g**) + : **i** = g * (erev - v) (exposed as **i**) + + + + + + +**Time Derivatives** + : d **A** /dt = -A / tauRise + : d **B** /dt = -B / tauDecay1 + : d **C** /dt = -C / tauDecay2 + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import ExpThreeSynapse + +variable = ExpThreeSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase1: 'a Nml2Quantity_conductance (required)' = None, + gbase2: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + tau_decay1: 'a Nml2Quantity_time (required)' = None, + tau_decay2: 'a Nml2Quantity_time (required)' = None, + tau_rise: 'a Nml2Quantity_time (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + + A synapse consisting of one rise and two decay time courses. + +``` +```` +````` + +(schema:baseblockmechanism)= + +## *baseBlockMechanism* + + + + +Base of any ComponentType which produces a varying scaling ( or blockage ) of synaptic strength of magnitude **scaling**. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**blockFactor**$ $Dimensionless + +``` +```` +````` + +(schema:voltageconcdepblockmechanism)= + +## voltageConcDepBlockMechanism + + + + +extends *{ref}`schema:baseblockmechanism`* + + + +Synaptic blocking mechanism which varys with membrane potential across the synapse, e.g. in NMDA receptor mediated synapses. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**blockConcentration**$ ${ref}`schema:dimensions:concentration` +**scalingConc**$ ${ref}`schema:dimensions:concentration` +**scalingVolt**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Text fields +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**species**$ + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**blockFactor**$ *(from {ref}`schema:baseblockmechanism`)* $Dimensionless + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **blockFactor** = 1/(1 + (blockConcentration / scalingConc)* exp(-1 * (v / scalingVolt))) (exposed as **blockFactor**) + + + + + + +```` +````` + +(schema:baseplasticitymechanism)= + +## *basePlasticityMechanism* + + + + +Base plasticity mechanism. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**plasticityFactor**$ $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ This is where the plasticity mechanism receives spike events from the parent synapse.$Direction: in + +``` +```` +````` + +(schema:tsodyksmarkramdepmechanism)= + +## tsodyksMarkramDepMechanism + + + + +extends *{ref}`schema:baseplasticitymechanism`* + + + +Depression-only Tsodyks-Markram model, as in Tsodyks and Markram 1997. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**initReleaseProb**$ $Dimensionless +**tauRec**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**plasticityFactor**$ *(from {ref}`schema:baseplasticitymechanism`)* $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ This is where the plasticity mechanism receives spike events from the parent synapse. *(from {ref}`schema:baseplasticitymechanism`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **parent** AS **a** +: WITH **this** AS **b** +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **R**: Dimensionless + + + + + + + + + +**On Start** +: **R** = 1 + + +**On Events** + +: EVENT IN on port: **in** +:    **R** = R * (1 - U) + + + + + +**Derived Variables** + : **U** = initReleaseProb + : **plasticityFactor** = R * U (exposed as **plasticityFactor**) + + + + + + +**Time Derivatives** + : d **R** /dt = (1 - R) / tauRec + + +```` +````` + +(schema:tsodyksmarkramdepfacmechanism)= + +## tsodyksMarkramDepFacMechanism + + + + +extends *{ref}`schema:baseplasticitymechanism`* + + + +Full Tsodyks-Markram STP model with both depression and facilitation, as in Tsodyks, Pawelzik and Markram 1998. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**initReleaseProb**$ $Dimensionless +**tauFac**$ ${ref}`schema:dimensions:time` +**tauRec**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**plasticityFactor**$ *(from {ref}`schema:baseplasticitymechanism`)* $Dimensionless + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ This is where the plasticity mechanism receives spike events from the parent synapse. *(from {ref}`schema:baseplasticitymechanism`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **parent** AS **a** +: WITH **this** AS **b** +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **R**: Dimensionless +: **U**: Dimensionless + + + + + + + + + +**On Start** +: **R** = 1 +: **U** = initReleaseProb + + +**On Events** + +: EVENT IN on port: **in** +:    **R** = R * (1 - U) +:    **U** = U + initReleaseProb * (1 - U) + + + + + +**Derived Variables** + : **plasticityFactor** = R * U (exposed as **plasticityFactor**) + + + + + + +**Time Derivatives** + : d **R** /dt = (1 - R) / tauRec + : d **U** /dt = (initReleaseProb - U) / tauFac + + +```` +````` + +(schema:blockingplasticsynapse)= + +## blockingPlasticSynapse + + + + +extends {ref}`schema:exptwosynapse` + + + +Biexponential synapse that allows for optional block and plasticity mechanisms, which can be expressed as child elements. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:voltage` +**gbase**$ Baseline conductance, generally the maximum conductance following a single spike *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**tauDecay**$ *(from {ref}`schema:exptwosynapse`)* ${ref}`schema:dimensions:time` +**tauRise**$ *(from {ref}`schema:exptwosynapse`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**peakTime**$ *(from {ref}`schema:exptwosynapse`)* ${ref}`schema:dimensions:time` +``` +   **peakTime** = log(tauDecay / tauRise) * (tauRise * tauDecay)/(tauDecay - tauRise) +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**waveformFactor**$ *(from {ref}`schema:exptwosynapse`)* $Dimensionless +``` +   **waveformFactor** = 1 / (-exp(-peakTime / tauRise) + exp(-peakTime / tauDecay)) + +```` + +````{tab-item} Children list +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**plasticityMechanisms**$ $ {ref}`schema:baseplasticitymechanism` +**blockMechanisms**$ $ {ref}`schema:baseblockmechanism` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**g**$ Time varying conductance through the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in +**relay**$ Used to relay incoming spikes to child plasticity mechanism$Direction: out + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **A**: Dimensionless +: **B**: Dimensionless + + + + + + + + + +**On Start** +: **A** = 0 +: **B** = 0 + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + (weight * plasticityFactor * waveformFactor) +:    **B** = B + (weight * plasticityFactor * waveformFactor) +:    EVENT OUT on port: **relay** + + + + + +**Derived Variables** + : **plasticityFactor** = plasticityMechanisms[*]->plasticityFactor(reduce method: multiply) + : **blockFactor** = blockMechanisms[*]->blockFactor(reduce method: multiply) + : **g** = blockFactor * gbase * (B - A) (exposed as **g**) + : **i** = g * (erev - v) (exposed as **i**) + + + + + + +**Time Derivatives** + : d **A** /dt = -A / tauRise + : d **B** /dt = -B / tauDecay + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import BlockingPlasticSynapse + +variable = BlockingPlasticSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + gbase: 'a Nml2Quantity_conductance (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, + tau_decay: 'a Nml2Quantity_time (required)' = None, + tau_rise: 'a Nml2Quantity_time (required)' = None, + plasticity_mechanism: 'a PlasticityMechanism (optional)' = None, + block_mechanism: 'a BlockMechanism (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + + +``` +```{code-block} xml + + A biexponential blocking synapse, with STD. + + + +``` +```{code-block} xml + + A biexponential blocking synapse with short term + depression and facilitation. + + + +``` +```` +````` + +(schema:doublesynapse)= + +## doubleSynapse + + + + +extends *{ref}`schema:basevoltagedepsynapse`* + + + +Synapse consisting of two independent synaptic mechanisms ( e.g. AMPA-R and NMDA-R ), which can be easily colocated in connections. + + +`````{tab-set} +````{tab-item} Paths +```{csv-table} +:widths: 1, 7 +:width: 100% +:delim: $ + +**synapse1Path**$ +**synapse2Path**$ + +```` + +````{tab-item} Component References +```{csv-table} +:widths: 1, 7, 2 +:width: 100% +:delim: $ + +**synapse1**$ $ {ref}`schema:basesynapse` +**synapse2**$ $ {ref}`schema:basesynapse` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in +**relay**$ Used to relay incoming spikes to child mechanisms$Direction: out + +``` +```` + +````{tab-item} Dynamics + +**Structure** +: WITH **this** AS **a** +: WITH **synapse1Path** AS **b** +: WITH **synapse2Path** AS **c** +: CHILD INSTANCE: **synapse1** +: CHILD INSTANCE: **synapse2** +: EVENT CONNECTION from **a** TO **c** + +: EVENT CONNECTION from **a** TO **b** + + + + + +**State Variables** +: **weightFactor**: Dimensionless + + + + + + + + + + + +**On Events** + +: EVENT IN on port: **in** +:    **weightFactor** = weight +:    EVENT OUT on port: **relay** + + + + + +**Derived Variables** + : **i1** = synapse1->i + : **i2** = synapse2->i + : **i** = weightFactor * (i1 + i2) (exposed as **i**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import DoubleSynapse + +variable = DoubleSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + synapse1: 'a NmlId (required)' = None, + synapse2: 'a NmlId (required)' = None, + synapse1_path: 'a string (required)' = None, + synapse2_path: 'a string (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + + A single "synapse" which contains both AMPA and NMDA. It is planned that the need for extra synapse1Path/synapse2Path attributes can be removed in later versions. + +``` +```` +````` + +(schema:stdpsynapse)= + +## stdpSynapse + + + + +extends {ref}`schema:exptwosynapse` + + + +Spike timing dependent plasticity mechanism, NOTE: EXAMPLE NOT YET WORKING!!!! + + +[Bioportal entry for Computational Neuroscience Ontology related to stdpSynapse.](https://bioportal.bioontology.org/ontologies/CNO/?p=classes&conceptid=cno_0000034) + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**erev**$ Reversal potential of the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:voltage` +**gbase**$ Baseline conductance, generally the maximum conductance following a single spike *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**tauDecay**$ *(from {ref}`schema:exptwosynapse`)* ${ref}`schema:dimensions:time` +**tauRise**$ *(from {ref}`schema:exptwosynapse`)* ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**tsinceRate** = 1$ $ Dimensionless +**longTime** = 1000s$ $ {ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Derived parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**peakTime**$ *(from {ref}`schema:exptwosynapse`)* ${ref}`schema:dimensions:time` +``` +   **peakTime** = log(tauDecay / tauRise) * (tauRise * tauDecay)/(tauDecay - tauRise) +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**waveformFactor**$ *(from {ref}`schema:exptwosynapse`)* $Dimensionless +``` +   **waveformFactor** = 1 / (-exp(-peakTime / tauRise) + exp(-peakTime / tauDecay)) + +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**M**$ $Dimensionless +**P**$ $Dimensionless +**g**$ Time varying conductance through the synapse *(from {ref}`schema:baseconductancebasedsynapse`)* ${ref}`schema:dimensions:conductance` +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` +**tsince**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ The current may vary with the voltage exposed by the ComponentType on which this is placed *(from {ref}`schema:basevoltagedepsynapse`)* ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **A**: Dimensionless +: **B**: Dimensionless +: **M**: Dimensionless  (exposed as **M**) +: **P**: Dimensionless  (exposed as **P**) +: **tsince**: {ref}`schema:dimensions:time`  (exposed as **tsince**) + + + + + + + + + +**On Start** +: **A** = 0 +: **B** = 0 +: **M** = 1 +: **P** = 1 +: **tsince** = longTime + + +**On Events** + +: EVENT IN on port: **in** +:    **A** = A + waveformFactor +:    **B** = B + waveformFactor +:    **tsince** = 0 + + + + + +**Derived Variables** + : **g** = gbase * (B - A) (exposed as **g**) + : **i** = g * (erev - v) (exposed as **i**) + + + + + + +**Time Derivatives** + : d **A** /dt = -A / tauRise + : d **B** /dt = -B / tauDecay + : d **tsince** /dt = tsinceRate + + +```` +````` + +(schema:gapjunction)= + +## gapJunction + + + + +extends *{ref}`schema:basesynapse`* + + + +Gap junction/single electrical connection. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **vpeer** = peer->v + : **i** = weight * conductance * (vpeer - v) (exposed as **i**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import GapJunction + +variable = GapJunction( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + conductance: 'a Nml2Quantity_conductance (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:basegradedsynapse)= + +## *baseGradedSynapse* + + + + +extends *{ref}`schema:basesynapse`* + + + +Base type for graded synapses. + + +`````{tab-set} +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` +````` + +(schema:silentsynapse)= + +## silentSynapse + + + + +extends *{ref}`schema:basegradedsynapse`* + + + +Dummy synapse which emits no current. Used as presynaptic endpoint for analog synaptic connection. + + +`````{tab-set} +````{tab-item} Constants +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**AMP** = 1A$ $ {ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **vpeer** = peer->v + : **i** = 0 * AMP (exposed as **i**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import SilentSynapse + +variable = SilentSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` + +(schema:lineargradedsynapse)= + +## linearGradedSynapse + + + + +extends *{ref}`schema:basegradedsynapse`* + + + +Behaves just like a one way gap junction. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**conductance**$ ${ref}`schema:dimensions:conductance` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + + + + + + +**Derived Variables** + : **vpeer** = peer->v + : **i** = weight * conductance * (vpeer - v) (exposed as **i**) + + + + + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import LinearGradedSynapse + +variable = LinearGradedSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + conductance: 'a Nml2Quantity_conductance (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```` +````` + +(schema:gradedsynapse)= + +## gradedSynapse + + + + +extends *{ref}`schema:basegradedsynapse`* + + + +Graded/analog synapse. Based on synapse in Methods of http://www.nature.com/neuro/journal/v7/n12/abs/nn1352.html. + + +`````{tab-set} +````{tab-item} Parameters +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**Vth**$ The half-activation voltage of the synapse ${ref}`schema:dimensions:voltage` +**conductance**$ ${ref}`schema:dimensions:conductance` +**delta**$ Slope of the activation curve ${ref}`schema:dimensions:voltage` +**erev**$ The reversal potential of the synapse ${ref}`schema:dimensions:voltage` +**k**$ Rate constant for transmitter-receptor dissociation rate ${ref}`schema:dimensions:per_time` + +``` +```` + +````{tab-item} Properties +```{csv-table} +:widths: 3, 5, 2 +:width: 100% +:delim: $ + +**weight** (default: 1)$ $ Dimensionless + +``` +```` + +````{tab-item} Exposures +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**i**$ The total (usually time varying) current produced by this ComponentType *(from {ref}`schema:basepointcurrent`)* ${ref}`schema:dimensions:current` +**inf**$ $Dimensionless +**tau**$ ${ref}`schema:dimensions:time` + +``` +```` + +````{tab-item} Requirements +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**v**$ ${ref}`schema:dimensions:voltage` + +``` +```` + +````{tab-item} Event Ports +```{csv-table} +:widths: 1, 7, 2 +:width: 100 % +:delim: $ + +**in**$ *(from {ref}`schema:basesynapse`)*$Direction: in + +``` +```` + +````{tab-item} Dynamics + + + +**State Variables** +: **s**: Dimensionless + + + + + + + + + + + + +**On Conditions** + +: IF (1-inf) < 1e-4 THEN +:    **s** = inf + + + + + +**Derived Variables** + : **vpeer** = peer->v + : **inf** = 1/(1 + exp((Vth - vpeer)/delta)) (exposed as **inf**) + : **tau** = (1-inf)/k (exposed as **tau**) + : **i** = weight * conductance * s * (erev-v) (exposed as **i**) + + + + +**Conditional Derived Variables** + +: IF (1-inf) > 1e-4 THEN +:   **s_rate** = (inf - s)/tau +: OTHERWISE +:   **s_rate** = 0 + + +**Time Derivatives** + : d **s** /dt = s_rate + + +```` + +````{tab-item} Schema +```{code-block} xml + + + + + + + + + + + + +``` +```` + +````{tab-item} Usage: Python +*Go to the libNeuroML documentation* +```{code-block} python +from neuroml import GradedSynapse + +variable = GradedSynapse( + id: 'a NmlId (required)' = None, + metaid: 'a MetaId (optional)' = None, + notes: 'a string (optional)' = None, + properties: 'list of Property(s) (optional)' = None, + annotation: 'a Annotation (optional)' = None, + neuro_lex_id: 'a NeuroLexId (optional)' = None, + conductance: 'a Nml2Quantity_conductance (required)' = None, + delta: 'a Nml2Quantity_voltage (required)' = None, + Vth: 'a Nml2Quantity_voltage (required)' = None, + k: 'a Nml2Quantity_pertime (required)' = None, + erev: 'a Nml2Quantity_voltage (required)' = None, +) +``` +```` +````{tab-item} Usage: XML +```{code-block} xml + +``` +```{code-block} xml + +``` +```` +````` diff --git a/_sources/Userdocs/SimulatingNeuroMLModels.md b/_sources/Userdocs/SimulatingNeuroMLModels.md new file mode 100644 index 00000000..3b902498 --- /dev/null +++ b/_sources/Userdocs/SimulatingNeuroMLModels.md @@ -0,0 +1,169 @@ +(userdocs:simulators)= +# Simulating NeuroML Models + +```{admonition} Validate NeuroML 2 files before using them. +:class: tip +It is good practice to {ref}`validate NeuroML 2 files ` to check them for correctness before simulating them. +``` +(userdocs:simulating_models:osb)= +## Using Open Source Brain + +Models that have already been converted to NeuroML and added to the [Open Source Brain](https://www.opensourcebrain.org/) platform can be simulated through your browser. + +```{figure} ../images/OSBv1.png +:alt: Open Source Brain +:align: center +:scale: 25 % + +Examples of NeuroML 2 models visualised on Open Source Brain. A) [Hodgkin Huxley model](https://www.opensourcebrain.org/projects/hodgkin-huxley-tutorial?explorer=https%3A%2F%2Fraw.githubusercontent.com%2Fopensourcebrain%2Ftutorials%2Fdevelopment%2Fmodels%2FhodgkinHuxley%2FGEPPETTO.json) interactive tutorial. B) Integrate and fire network model of cortical column ([Potjans and Diesmann 2014](https://www.opensourcebrain.org/projects/potjansdiesmann2014)), showing network connectivity. C) Cortical model with multicompartmental cells ([Traub et al. 2005](https://www.opensourcebrain.org/projects/thalamocortical)), showing network properties and simulated membrane potential activity. D) Model of C. elegans nervous system from [OpenWorm project](https://www.opensourcebrain.org/projects/c302/). All visualisation/analysis/simulation enabled due to models being in standardised NeuroML format. + +``` +Most of the [OSB example projects](https://www.opensourcebrain.org/projects) feature prebuilt NeuroML models which can be simulated in this way. + +A discussion on the steps required for sharing your own models on OSB, with a view to simulating them on the platform, can be found {ref}`here `. + +(userdocs:simulating_models:jlems)= +(userdocs:simulating_models:jnml)= +## Using jNeuroML/pyNeuroML + +{ref}`jLEMS ` is the reference implementation of the LEMS language in Java, and can be used to simulate single compartment models written in NeuroML/LEMS. +It is included in both {ref}`jNeuroML ` and {ref}`pyNeuroML `. + +```{figure} ../images/pynml_jnml.svg +:alt: jNeuroML and pyNeuroML +:align: center +:width: 500px + +Relationship between {ref}`jLEMS `, {ref}`jNeuroML ` and {ref}`pyNeuroML `. + +``` + +{ref}`jNeuroML ` and {ref}`pyNeuroML ` can be used at the command line as follows, when a {ref}`LEMS Simulation file ` has been created to describe what to simulate/plot/save: + +```{code-block} console +# Simulate the model using jNeuroML +jnml + +# Simulate the model using pyNeuroML +pynml +``` + +You can also run LEMS simulations using jNeuroML straight from a Python script using the {ref}`pyNeuroML ` API: + +```{code-block} python +from pyneuroml.pynml import run_lems_with_jneuroml + +... + +run_lems_with_jneuroml(lems_file_name) +``` + +(userdocs:simulating_models:neuron)= +## Using NEURON + +For more complex models that can not be simulated using jLEMS (e.g. incorporating multicompartmental cells), we can use the {ref}`NEURON ` simulator, also using {ref}`jNeuroML ` or {ref}`pyNeuroML `, pointing at a {ref}`LEMS Simulation file ` describing what to simulate, and using the `-neuron` option: + +```{code-block} console +# Simulate the model using NEURON with python/hoc/mod files generated by jNeuroML +jnml -neuron -run + +# Simulate the model using NEURON with python/hoc/mod files generated by pyNeuroML +pynml -neuron -run +``` + +You can also run LEMS simulations using the NEURON simulator using the {ref}`pyNeuroML ` API: + +```{code-block} python +from pyneuroml.pynml import run_lems_with_jneuroml_neuron + +... + +run_lems_with_jneuroml_neuron(lems_file_name) +``` +There is a **dedicated page on NEURON/NeuroML interactions** {ref}`here `. + + +(userdocs:simulating_models:netpyne)= +## Using NetPyNE + +You can also generate and run [NetPyNE](https://netpyne.org) code from NeuroML. +To generate and run NetPyNE code, use {ref}`jNeuroML ` or {ref}`pyNeuroML `: + +```{code-block} console +# Simulate the model using NetPyNE with python/hoc/mod files generated by jNeuroML +jnml -netpyne -run + +# Simulate the model using NetPyNE with python/hoc/mod files generated by pyNeuroML +pynml -netpyne -run +``` + +The main generated Python file name will end in `_netpyne.py`. + +You can also run LEMS simulations using the NetPyNE simulator using the {ref}`pyNeuroML ` API: + +```{code-block} python +from pyneuroml.pynml import run_lems_with_jneuroml_netpyne + +... + +run_lems_with_jneuroml_netpyne(lems_file_name) +``` + +There is a **dedicated page on NetPyNE/NeuroML interactions** {ref}`here `. + + +(userdocs:simulating_models:brian2)= +## Using Brian2 + +You can export single component NeuroML models to Python scripts for running them using the [Brian2](https://briansimulator.org) simulator: + +```{code-block} console +# Using jnml +jnml -brian2 + +# Using pynml +pynml -brian2 +``` + +You can also run LEMS simulations using the Brian2 simulator using the {ref}`pyNeuroML ` API: + +```{code-block} python +from pyneuroml.pynml import run_lems_with_jneuroml_brian2 + +... + +run_lems_with_jneuroml_brian2(lems_file_name) +``` + +There is a **dedicated page on Brian/NeuroML interactions** {ref}`here `. + +(userdocs:simulating_models:moose)= +## Using MOOSE + +You can export NeuroML models to the MOOSE simulator format using {ref}`jNeuroML ` or {ref}`pyNeuroML `, pointing at a {ref}`LEMS Simulation file ` describing what to simulate, and using the `-moose` option: + +```{code-block} console +# Using jnml +jnml -moose + +# Using pynml +pynml -moose +``` +There is a **dedicated page on MOOSE/NeuroML interactions** {ref}`here `. + + +(userdocs:simulating_models:eden)= +## Using EDEN + +The EDEN simulator can load and simulate NeuroML v2 models. + +There is a **dedicated page on EDEN/NeuroML interactions** {ref}`here `. + + + +(userdocs:simulating_models:arbor)= +## Using Arbor + +You can import NeuroML models to the Arbor simulator. + +There is a **dedicated page on Arbor/NeuroML interactions** {ref}`here `. diff --git a/_sources/Userdocs/SingleCompartmentHHExample.md b/_sources/Userdocs/SingleCompartmentHHExample.md new file mode 100644 index 00000000..a108f3a7 --- /dev/null +++ b/_sources/Userdocs/SingleCompartmentHHExample.md @@ -0,0 +1,460 @@ +(userdocs:getting_started:single_compartment_example)= +# Simulating a single compartment Hodgkin-Huxley neuron + +In this section we will model and simulate a Hodgkin-Huxley (HH) neuron ({cite}`Hodgkin1952`). +A Hodgkin-Huxley neuron includes Sodium (Na), Potassium (K), and leak ion channels. +For further information on this neuron model, please see [here](https://hodgkin-huxley-tutorial.readthedocs.io/en/latest/index.html). + +```{figure} ../Userdocs/NML2_examples/HH_single_compartment_example_sim-v.png +:alt: Membrane potential for neuron recorded from the simulation +:align: center + +Membrane potential of the simulated Hodgkin-Huxley neuron. +``` +This plot, saved as `HH_single_compartment_example_sim-v.png` is generated using the following Python NeuroML script: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +---- +``` +(userdocs:getting_started:single_compartment_example:model)= +## Declaring the model in NeuroML + +Similar to previous examples, we will first declare the model, visualise it, and then simulate it. +The HH neuron model is more complex than the {ref}`Izhikevich neuron model ` we have seen so far. +For example, it includes voltage-gated ion channels. +We will first implement these ion channels in NeuroML, then add them to a cell. +We will then create a network of one cell which will will stimulate with external input to record the membrane potential. + +As you can also see in the script, since this is a slightly more complex model, we have modularised our code into different functions that carry out different tasks. +Let us now step through the script in a bottom-up fashion. +We start with the ion channels and build the network simulation. + +(userdocs:getting_started:single_compartment_example:model:channels)= +### Declaring ion channels + +```{admonition} Note: you might not need to define your ion channels in Python every time.... +In this example, all parts of the model, including the ion channels, are defined from scratch in Python and then NeuroML files in XML are generated and saved. For many modelling projects however, ion channel XML files will be reused from other models, and can just be included in the cells that use them with: ``. See {ref}` here ` for tips on where to find ion channel models in NeuroML. +``` + +Let us look at the definition of the Sodium (Na) channel in NeuroML: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 106-168 +---- +``` +Here, we define the two gates, `m` and `h`, with their forward and reverse rates and add them to the channel. +Next, we create a NeuroML document and save this channel (only this channel that we've just defined) to a NeuroML file and validate it. +So we now have our Na channel defined in a separate NeuroML file that can be used in multiple models and shared: +```{literalinclude} ./NML2_examples/HH_example_na_channel.nml +---- +language: xml +``` +The various rate equations ({ref}`HHExpLinearRate `, {ref}`HHExpRate `, {ref}`HHSigmoidRate ` that can be used in the gate (here {ref}`gateHHrates `, but other forms such as {ref}`gateHHtauInf ` and {ref}`gateHHInstantaneous ` can be used) are defined in the NeuroML {ref}`schema `. + +Also note that since we'll want to *include* this file in other NeuroML files, we make the function return the name of the file. +This is an implementation detail, and there are other ways of doing this too. +We could have hard-coded this in all our functions or defined it as a global variable in the script for example. +If we were using object-oriented programming, we could have created a class and stored this information as a class or object variable. + +The K and leak channels are defined in a similar way: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 171-245 +---- +``` +They are also saved in their own NeuroML files, which have also been validated. +The file for the K channel: +```{literalinclude} ./NML2_examples/HH_example_k_channel.nml +---- +language: xml +``` +For the leak channel: +```{literalinclude} ./NML2_examples/HH_example_leak_channel.nml +---- +language: xml +``` +(userdocs:getting_started:single_compartment_example:model:cell)= +### Declaring the cell + +Now that we have declared our ion channels, we can start constructing our {ref}`cell ` in a different function. +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 247-318 +---- +``` +Let us walk through this function: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 161-168 +---- +``` +We start by creating a new NeuroML document that we will use to save this cell, and adding the cell to it. + +A {ref}`Cell ` component has a number of child/children components that we need to now populate: +```{code-block} pycon +Cell -- Cell with **segment** s specified in a **morphology** element along with details on its **biophysicalProperties** . NOTE: this can only be correctly simulated using jLEMS when there is a single segment in the cell, and **v** of this cell represents the membrane potential in that isopotential segment. + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for Cell are: +* morphology_attr (class: NmlId, Optional) +* biophysical_properties_attr (class: NmlId, Optional) +* morphology (class: Morphology, Optional) + * Contents ('ids'/): 'morphology' + +* neuro_lex_id (class: NeuroLexId, Optional) +* metaid (class: MetaId, Optional) +* biophysical_properties (class: BiophysicalProperties, Optional) + * Contents ('ids'/): 'biophys' + +* id (class: NmlId, Required) + * Contents ('ids'/): hh_cell + +* notes (class: xs:string, Optional) + * Contents ('ids'/): A single compartment HH cell + +* properties (class: Property, Optional) +* annotation (class: Annotation, Optional) +``` +We can see that the {ref}`morphology ` and {ref}`biophysical properties ` components have already been initialised for us. +We now need to add the required components to them. + +We begin with the biophysical properties. +Biophysical properties are themselves split into two: +- the {ref}`membrane properties ` +- the {ref}`intracellular properties ` + +Let us look at membrane properties first. +The {ref}`schema ` shows that membrane properties has two *child* elements: + +- {ref}`initMembPotential ` +- {ref}`spikeThresh ` + +and three *children* elements: + +- {ref}`specificCapacitances ` +- {ref}`populations ` +- {ref}`channelDensities ` +```{admonition} Child elements vs Children elements +:class: tip +When an element specifies a **Child** subelement, it will only have one of these present (it could have zero). **Children** explicitly says that there can be zero, one or many subelements. +``` + +So, we start with the ion-channels which are distributed along the membrane with some density. +A number of helpful functions are available to us: `add_channel_density`, `add_membrane_property`, `set_specific_capacitance`, `set_init_memb_potential`: +For example, for the Na channels: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 262-271 +---- +``` +and similarly for the K and leak channels. +Now, since the ion-channels were created in other files, we need to make this document aware of their declarations. +To do this, reference the other files in the `ion_chan_def_file` argument of the `add_channel_density` method. +Under the hood, this will `include` the ion channel definition file we have created in this cell document using an `IncludeType` component. +Each document we want to include gets appended to the list of `includes` for the document. + +Next, we add the other child and children elements: the {ref}`Specific Capacitance `, the {ref}`Spike Threshold `, the {ref}`InitMembPotential `. +This completes the membrane properties. +We then add the intracellular properties next: {ref}`Resistivity `. +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 294-299 +---- +``` +Next, we add the {ref}`Morphology ` related information for our cell. +Here, we are only creating a single compartment cell with only one segment. +We will look into multi-compartment cells with more segments in later examples: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 303-311 +---- +``` +A {ref}`segment ` has `proximal` and `distal` child elements which describe the extent of the segment. +These are described using a {ref}`Point3DWithDiam ` object, which the `add_segment` function creates for us. + + +This completes our cell. +We add it to our NeuroML document, and save (and validate) it. +The resulting NeuroML file is: +```{literalinclude} ./NML2_examples/HH_example_cell.nml +---- +language: xml +``` +We now have our cell defined in a separate NeuroML file, that can be re-used and shared. + +(userdocs:getting_started:single_compartment_example:model:network)= +### Declaring the network + +We now use our cell in a network. +A {ref}`network in NeuroML ` has multiple children elements: {ref}`populations `, {ref}`projections `, {ref}`inputLists ` and so on. +Here we are going to only create a network with one cell, and an {ref}`explicit input ` to the cell: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 320-358 +---- +``` +We start in the same way, by creating a new NeuroML document and including our cell file into it. +We then create a {ref}`population ` comprising of a single cell. +We create a {ref}`pulse generator ` as an {ref}`explicit input `, which targets our population. +Note that as the schema documentation for `ExplicitInput` notes, any current source (any component that *extends* {ref}`basePointCurrent `) can be used as an `ExplicitInput`. + +We add all of these to the {ref}`network ` and save (and validate) our network file. +The NeuroML file generated is below: +```{literalinclude} ./NML2_examples/HH_example_net.nml +---- +language: xml +``` +(userdocs:getting_started:single_compartment_example:model:generatedmodel)= +### The generated NeuroML model + +Before we look at simulating the model, we can inspect our model to check for correctness. +All our NeuroML files were validated when they were created already, so we do not need to run this step again. +However, if required, this can be easily done: +```{code-block} console +pynml -validate HH_*nml +``` +Next, we can visualise our model using the information noted in the {ref}`visualising NeuroML models ` page (including the `-v` verbose option for more information on the cell): +```{code-block} console +pynml-summary HH_example_net.nml -v +******************************************************* +* NeuroMLDocument: network +* +* IonChannelHH: ['k_channel', 'leak_channel', 'na_channel'] +* PulseGenerator: ['pg'] +* +* Cell: hh_cell +* +* Parent segment: None (root segment) +* (0.0, 0.0, 0.0), diam 17.841241161527712um -> (0.0, 0.0, 0.0), diam 17.841241161527712um; seg length: 0.0 um +* Surface area: 1000.0 um2, volume: 2973.5401935879518 um3 +* Total length of 1 segment: 0.0 um; total area: 1000.0 um2 +* +* Channel density: na_channels on all; conductance of 120.0 mS_per_cm2 through ion chan na_channel with ion na, erev: 50.0 mV +* Channel is on , total conductance: 1200.0 S_per_m2 x 1e-09 m2 = 1.2000000000000002e-06 S (1200000.0000000002 pS) +* Channel density: k_channels on all; conductance of 360 S_per_m2 through ion chan k_channel with ion k, erev: -77mV +* Channel is on , total conductance: 360.0 S_per_m2 x 1e-09 m2 = 3.6000000000000005e-07 S (360000.00000000006 pS) +* Channel density: leak_channels on all; conductance of 3.0 S_per_m2 through ion chan leak_channel with ion non_specific, erev: -54.3mV +* Channel is on , total conductance: 3.0 S_per_m2 x 1e-09 m2 = 3.0000000000000004e-09 S (3000.0000000000005 pS) +* +* Specific capacitance on all: 1.0 uF_per_cm2 +* Capacitance of , total capacitance: 0.01 F_per_m2 x 1e-09 m2 = 1.0000000000000001e-11 F (10.000000000000002 pF) +* +* Network: single_hh_cell_network +* +* 1 cells in 1 populations +* Population: pop0 with 1 components of type hh_cell +* +* 0 connections in 0 projections +* +* 0 inputs in 0 input lists +* +* 1 explicit inputs (outside of input lists) +* Explicit Input of type pg to pop0(cell 0), destination: unspecified +* +******************************************************* +``` +Since our model is a single compartment model with only one cell, it doesn't have any 3D structure to visualise. +We can check the connectivity graph of the model: + +```{code-block} console +pynml -graph 10 HH_example_net.nml +``` +which will give us this figure: +```{figure} ./NML2_examples/single_hh_cell_network.gv.png +:alt: Level 10 network graph generated by pynml +:align: center +:scale: 60 % + +Level 10 network graph generated by pynml +``` +(userdocs:getting_started:single_compartment_example:model:generatedmodel:analysingchannels)= +#### Analysing channels + +Finally, we can analyse the ion channels that we've declared using the `pynml-channelanalysis` utility: +```{code-block} console +pynml-channelanalysis HH_example_k_channel.nml +``` +This generates graphs to show the behaviour of the channel: + +
+
+
+
+ +```{figure} ./NML2_examples/HH_example_k_channel_2.png +:alt: Steady state behaviour of the K ion channel +:align: center +:scale: 60 % + +Steady state behaviour of the K ion channel. +``` +
+ +
+
+
+ + +```{figure} ./NML2_examples/HH_example_k_channel_1.png +:alt: Time course of the K ion channel +:align: center +:scale: 60 % + +Time course of the K ion channel. +``` + +
+ +
+
+
+ +Similarly, we can get these for the Na channel also: +```{code-block} console +pynml-channelanalysis HH_example_na_channel.nml + +``` + +
+
+
+
+ +```{figure} ./NML2_examples/HH_example_na_channel_2.png +:alt: Steady state behaviour of the Na ion channel +:align: center +:scale: 60 % + +Steady state behaviour of the Na ion channel. +``` +
+ +
+
+
+ + +```{figure} ./NML2_examples/HH_example_na_channel_1.png +:alt: Time course of the Na ion channel +:align: center +:scale: 60 % + +Time course of the Na ion channel. +``` + +
+ +
+
+
+ +(userdocs:getting_started:single_compartment_example:simulating)= +## Simulating the model + +Now that we have declared and inspected our network model and all its components, we can proceed to simulate it. +We do this in the `main` function: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 22-63 +---- +``` +Here we first create a `LEMSSimulation` instance and include our network NeuroML file in it. +We must inform LEMS what the target of the simulation is. +In our case, it's the id of our network, `single_hh_cell_network`: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 29-36 +---- +``` +We also want to record some information, so we create an output file first with an `id` of `output0`: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 39 +---- +``` +Now, we can record any quantity that is exposed by NeuroML (any `exposure`). +For example, we add a column for the membrane potential `v` of the {ref}`cell ` which would be the *0th* (and only) cell in our population `pop0`: `pop0[0]/v`. +We can also record the current in the channels: `pop[0]/iChannels` +We can also record the {ref}`current density ` `iDensity` for the channels, so we also record these. +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 40-55 +---- +``` +We then save the LEMS simulation file, run our simulation with the default {ref}`jNeuroML ` simulator. + +(userdocs:getting_started:single_compartment_example:plotting)= +## Plotting the recorded variables + +To plot the variables that we recorded, we read the data and use the `generate_plot` utility function: +```{literalinclude} ./NML2_examples/hh-single-compartment.py +---- +language: python +lines: 66-103 +---- +``` +This generates the following graphs: + +
+
+
+
+ +```{figure} ./NML2_examples/HH_single_compartment_example_sim-v.png +:alt: Membrane potential +:align: center +:scale: 60 % + +Membrane potential +``` +
+ +
+
+
+ +```{figure} ./NML2_examples/HH_single_compartment_example_sim-i.png +:alt: Channel current +:align: center +:scale: 60 % + +Channel current. +``` +
+ +
+
+
+ +```{figure} ./NML2_examples/HH_single_compartment_example_sim-iden.png +:alt: Channel current densities +:align: center +:scale: 60 % + +Channel current densities +``` + +
+ +
+
+
+ + +This concludes out third example. +Here we have seen how to create, simulate, record, and visualise a single compartment Hodgkin-Huxley neuron. +In the next section, you will find an interactive notebook where you can play with this example. diff --git a/_sources/Userdocs/SingleNeuronExample.md b/_sources/Userdocs/SingleNeuronExample.md new file mode 100644 index 00000000..d3700c82 --- /dev/null +++ b/_sources/Userdocs/SingleNeuronExample.md @@ -0,0 +1,633 @@ +(userdocs:getting_started:single_example)= +# Simulating a regular spiking Izhikevich neuron + +```{admonition} See also the interactive version. +:class: tip +Note: this is a more detailed description of the first example which is available as an {doc}`interactive Juptyer notebook <./NML2_examples/SingleNeuron>` on the next page. +``` +In this section, we wish to simulate a single regular spiking Izhikevich neuron ({cite}`Izhikevich2007`) and record/visualise its membrane potential (as shown in the figure below): + +```{figure} ../Userdocs/NML2_examples/example-single-izhikevich2007cell-sim-v.png +:alt: Membrane potential for neuron recorded from the simulation +:align: center + +Membrane potential of the simulated regular spiking Izhikevich neuron. +``` +This plot, saved as `example-single-izhikevich2007cell-sim-v.png`, is generated using the following Python NeuroML script: +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +---- +``` + +(userdocs:getting_started:single_example:declaring)= +## Declaring the model in NeuroML + +```{admonition} Python is the suggested programming language to use for working with NeuroML. +The Python NeuroML tools and libraries provide a convenient, easy to use interface to use NeuroML. +``` +Let us step through the different sections of the Python script. +To start writing a model in NeuroML, we first create a `NeuroMLDocument`. +This "document" represents the complete model and is the top level container for everything that the model should contain. + +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 21 +---- +``` +Let us define an Izhikevich cell that we will use to simulate a neuron. +The Izhikevich neuron model can take sets of parameters to exhibit different types of spiking behaviour. +Here, we define a component (object) of the general Izhikevich cell using parameters to show regular spiking. +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 34-38 +---- +``` + + +Now that the neuron has been defined and added to the document, we declare a {ref}`network ` with a {ref}`population ` of these neurons to create a network in a similar way. +Here, our model includes one network which includes only one population, which in turn only consists of a single neuron. +Once the network, its populations, and their neurons have been declared, we again add them to our model: +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 58-62 +---- +``` + +Question: why did we disable validation when we created the new network component? +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 58 +---- +``` +Let us try creating a network without disabling validation: +```python +net = nml_doc.add("Network", id="IzNet") +``` +It will throw a validation error: +``` +ValueError: Validation failed: +- Number of values for populations is below the minimum allowed, expected at least 1, found 0 +``` +This is because a network must have at least one population for it to be valid. +To fix this, we can either create the population before the network, or we can disable validation. +Here we chose to disable validation because we knew we were immediately creating our population and adding it to our network. + +Moving on, since we are providing a single input to the single cell in our network, we can add an `ExplicitInput` to our network. +See the supplementary section on the `info` function below to learn how you can find out that `ExplicitInput` could be used here. + +The list of inputs included in the NeuroML specification can be found on the {ref}`inputs ` page. +We use a {ref}`pulse generator ` here, creating a new component and adding it to our NeuroML document. +To connect it to our neuron, we specify the neuron as the `target` using an {ref}`explicit input `. +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 64-71 +---- +``` +This completes our model. +It includes a single network, with one population of one neuron that is driven by one pulse generator. +At this point, we can save our model to a file and validate it again to check if it conforms to the NeuroML schema (more on this {ref}`later `). +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 74-78 +---- +``` +Note that the validation here will re-run the tests our component factory and other methods use, but it also runs a series of additional tests that can only be run on the complete model. +So, it is necessary to validate the model after it has been fully constructed. + +(userdocs:getting_started:single_example:simulating)= +## Simulating the model + +Until now, we have just declared the model in NeuroML. We have not, however, included any information related to the simulation of this model, e.g. how long to run it for, what to save from the simulation etc. + +With NeuroML v2, the information required to simulate the model is provided using a {ref}`LEMS Simulation file `. +We will not go into the details of LEMS just yet. +We will limit ourselves to the bits necessary to simulate our Izhikevich neuron only. + +The following lines of code instantiate a new simulation with certain simulation parameters: `duration`, `dt`, `simulation_seed`. +Additionally, they also define what information is being recorded from the simulation. +In this case, we create an output file, and then add a new column to record the membrane potential `v` from our one neuron in the one population in it. +You can read more about recording from NeuroML simulations {ref}`here `. + +Finally, like we had saved our NeuroML model to a file, we also save our LEMS document to a file. + +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 85-99 +---- +``` + +Finally, {ref}`pyNeuroML ` also includes functions that allow you to run the simulation from the Python script itself: +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 102-104 +---- +``` + +Here, we are running our simulation using the {ref}`jNeuroML ` simulator, which is bundled with {ref}`pyNeuroML `. +Since NeuroML is a well defined standard, models defined in NeuroML can also be run using other {ref}`supported simulators `. + +(userdocs:getting_started:single_example:plotting)= +## Plotting the recorded membrane potential + +Once we have simulated our model and the data has been collected in the specified file, we can analyse the data. +pyNeuroML also includes some helpful functions to quickly plot various recorded variables. +The last few lines of code shows how the membrane potential plot at the top of the page is generated. +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 108-114 +---- +``` + +On the next page, you will find an interactive Jupyter notebook where you can play with this example. +Click the "launch" button in the top right hand corner to run the notebook in a configured service. +*You do not need to install any software on your computer to run these notebooks.* + +(userdocs:getting_started:single_example:supplementary)= +## Supplementary information + +The sections here explain concepts that have been used above. +These will help give you a deeper understanding of NeuroML, so we do suggest you go through them also. + +(userdocs:getting_started:single_example:supplementary:model)= +### The generated NeuroML model XML + +Let us investigate the generated NeuroML XML file: +```{literalinclude} ./NML2_examples/izhikevich2007_single_cell_network.nml +---- +language: xml +``` +NeuroML files are written in XML. +So, they consist of tags and attributes and can be processed by general purpose XML tools. +Each entity between chevrons is a *tag*: `<..>`, and each tag may have multiple *attributes* that are defined using the `name=value` format. +For example `` is a tag, that contains the `id` attribute with value `NML2_SimpleIonChannel`. + +```{admonition} XML Tutorial +For details on XML, have a look through [this tutorial](https://www.w3schools.com/xml/). +``` +```{admonition} Is this XML well-formed? +:class: tip +A NeuroML file needs to be both 1) well-formed, as in complies with the general rules of the XML language syntax, and 2) valid, i.e. contains the expected NeuroML specific tags/attributes. + +Is the XML shown above well-formed? See for yourself. Copy the NeuroML file listed above and check it using an [online XML syntax checker](https://www.w3schools.com/xml/xml_validator.asp). +``` + +Let us step through this file to understand the different constructs used in it. +The first segment introduces the `neuroml` tag that includes information on the specification that this NeuroML file adheres to. +```{literalinclude} ./NML2_examples/izhikevich2007_single_cell_network.nml +---- +language: xml +lines: 1-1 +---- +``` + +The first attribute, `xmlns` defines the XML *namespace*. +All the tags that are defined for use in NeuroML are defined for use in the NeuroML namespace. +This prevents conflicts with other XML schemas that may use the same tags. +Read more on XML namespaces [here](https://en.wikipedia.org/wiki/XML_namespace). + +The remaining lines in this snippet refer to the *XML Schema* that is defined for NeuroML. +XML itself does not define any tags, so any tags can be used in a general XML document. +Here is an example of a valid XML document, a simple HTML snippet: + +```{code-block} xml + + +A title + + +``` +NeuroML, however, does not use these tags. +It defines its own set of standard tags using an [XML Schema](http://www.w3.org/2001/XMLSchema-instance). +In other words, the NeuroML XML schema defines the structure and contents of a valid NeuroML document. +Various tools can then compare NeuroML documents to the NeuroML Schema to validate them. + +```{admonition} Purpose of the NeuroML schema +The NeuroML Schema defines the structure and contents of a valid NeuroML document. +``` + +The `xmlns:xi` attribute documents that NeuroML has a defined XML Schema. +The next attribute, `xsi:schemaLocation` tells us the locations of the NeuroML Schema. +Here, two locations are provided: + +- the Web URL: [http://www.neuroml.org/schema/neuroml2](http://www.neuroml.org/schema/neuroml2), +- and the location of the Schema Definition file (an `xsd` file) relative to this example file in the GitHub repository. + +We will look at the NeuroML schema in detail in later sections. +All NeuroML files must include the `neuroml` tag, and the attributes related to the NeuroML Schema. +The last attribute, `id` is the identification (or the name) of this particular NeuroML document. + +The remaining part of the file is the *declaration* of the model and its dynamics: +```{literalinclude} ./NML2_examples/izhikevich2007_single_cell_network.nml +---- +language: xml +lines: 2-7 +---- +``` + +The cell, is defined in the `izhikevich2007Cell` tag, which has a number of attributes as we saw before (see {ref}`here ` for the schema definition): +- `id`: the name that we want to give to this cell. To refer to it later, for example, +- `v0`: the initial membrane potential for the cell, +- `C`: the leak conductance, +- `k`: conductance per voltage, +- `vr`: the membrane potential after a spike, +- `vt`: the threshold membrane potential, to detect a spike, +- `vpeak`: the peak membrane potential, +- `a`, `b`, `c`, and `d`: are parameters of the Izhikevich neuron model. + +Similarly, the `pulseGenerator` is also defined, and the `network` tag includes the `population` and `explicitInput`. +We observe that even though we have declared the entities, and the values for parameters that govern them, we do not state what and how these parameters are used. +This is because NeuroML is a [declarative language](https://en.wikipedia.org/wiki/Declarative_programming) that defines the structure of models. +We do not need to define how the dynamics of the different parts of the model are implemented. +As we will see further below, these are already defined in NeuroML. +```{admonition} NeuroML is a declarative language. +Users describe the various components of the model but do not need to worry about how they are implemented. +``` +We have seen how an Izhikevich cell can be declared in NeuroML, with all its parameters. + +As is evident, XML files are excellent for storing structured data, but may not be easy to write by hand. +However, NeuroML users *are not expected* to write in XML. +They should use the Python tools as demonstrated here. + +(userdocs:getting_started:single_example:supplementary:schema)= +### The schema + +Given that NeuroML develops a standard and defines what tags and attributes can be used, let us see how these are defined for the Izhikevich cell. +The Izhikevich cell is defined in version 2 of the NeuroML schema [here](https://github.com/NeuroML/NeuroML2/blob/master/Schemas/NeuroML2/NeuroML_v2.0.xsd#L1422): +```{code-block} xml + + + + + + + + + + + + + + + +``` + +The `xs:` prefix indicates that these are all part of an XML Schema. +The Izhikevich cell and all its parameters are defined in the schema. +As we saw before, parameters of the model are defined as attributes in NeuroML files. +So, here in the schema, they are also defined as `attributes` of the `complexType` that the schema describes. +The schema also specifies which of the parameters are necessary, and what their dimensions (units) are using the `use` and `type` properties. + +This schema gives us all the information we need to describe an Izhikevich cell in NeuroML. +Using the specification in the Schema, any number of Izhikevich cells can be defined in a NeuroML file with the necessary parameter sets to create networks of Izhikevich cells. + +(userdocs:getting_started:single_example:supplementary:lems)= +### The generated LEMS XML + +The generated LEMS simulation file is shown below: + +```{literalinclude} ./NML2_examples/LEMS_example-single-izhikevich2007cell-sim.xml +---- +language: xml +---- +``` +Similar to NeuroML, a {ref}`LEMS Simulation file ` also has a well defined structure, i.e., a set of valid tags which define the contents of the LEMS file. +We observe that whereas the NeuroML tags were related to the modelling parameters, the LEMS tags are related to simulation. +We also note that our NeuroML model has been "included" in the LEMS file, so that all entities defined there are now known to the LEMS simulation also. +Like NeuroML, *users are not expected to write the LEMS XML component by hand*. +They should continue to use the NeuroML Python tools. + +(userdocs:getting_started:single_example:supplementary:component_factory)= +### The component_factory() function + +In the code above, we've used the {code}`component_factory` utility function that is included in the {code}`neuroml.utils` module. +This is, as the name notes, a "factory function". +When we provide the name of a NeuroML component type (the Python class) to it +as the first argument along with any parameters, it will create a new component +(Python object) and return it to us to use, after running a few checks under +the hood: + +- is the created component valid? +- are all the necessary parameters set? +- are any extra parameters given? + +We will see some of these checks in action later as we create more components for our model. + +The `component_factory` can accept two forms. +We can either pass the component type (class) to the function, or we can pass its name as a string. +The difference is that we do not need to `import` the class in our script before using it if we specify its name as a string. +The component factory function will import the class for us for us internally. +Either form works, so you can choose which you prefer. +It is important to only remain consistent and use one form to aid readability. + +(userdocs:getting_started:single_example:supplementary:add)= +### The add() function + +We've used another utility method in the code above: `add`. +The `add` method calls the `component_factory` for us internally to create a new object of the required component. + +We could also use the `component_factory`, followed by `add`, which would result in the same thing: +```python +izh0 = component_factory( + "Izhikevich2007Cell", + id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV", + vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA") +nml_doc.add(izh0) +``` + +In fact, we could do it all without using either method: +```python +# from neuroml import Izhikevich2007Cell +izh0 = neuroml.Izhikevich2007Cell( + id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV", + vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA") +nml_doc.izhikevich2007_cells.append(izh0) +``` + +This last form is not suggested because here, the extra checks that the `component_factory` and `add` methods run are not carried out. +You also need to know the name of the variable in the `nml_doc` object to be able to append to it. +The output of the `info` method will list all the member names, but the `add` method inspects the parent component and places the child in the right place for us. + +An exercise here would be to try providing invalid arguments to the `add` or `component_factory` methods. +For example: + +- try giving the wrong units for a parameter +- try leaving out a parameter + +What happens? + +For example, I have used the wrong units for the `d` parameter here, `ms` instead of `pA`: +``` +# or +# izh0 = component_factory( +izh0 = nml_doc.add( + "Izhikevich2007Cell", + id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV", + vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100ms") +``` +and it will throw a `ValueError` telling us that this does not match the expected string for `d`: +``` +ValueError: Validation failed: +- Value "100ms" does not match xsd pattern restrictions: [['^(-?([0-9]*(\\.[0-9]+)?)([eE]-?[0-9]+)?[\\s]*(A|uA|nA|pA))$']] +``` +The specific error here includes the "pattern restrictions" ([regular expression](https://docs.python.org/3/howto/regex.html#regex-howto)) for valid values of the `d` parameter. +There are a number of tutorials on regular expressions on the internet that you can use to learn more about the meaning of the provided pattern restriction. +The one restriction that we are interested in here is that the value of `d` must end in one of `A`, `uA`, `nA`, or `pA`. +Anything else will result in an invalid value, and the factory will throw a `ValueError`. + +The NeuroML specification declares valid units for all its components. +This allows us to validate models and components while building the model---even before we have a complete model that we want to simulate. +In fact, NeuroML also defines a list of units and dimensions that can be used. +```{admonition} Units in NeuroML +NeuroML defines a {ref}`standard set of units ` that can be used in models. +Learn more about units and dimensions in NeuroML and LEMS {ref}`here `. +``` + +(userdocs:getting_started:single_example:supplementary:info)= +### The info() function + +Now that we have a document, what if we want to inspect it to see what components it can hold, and what its current contents are? +Each NeuroML component type includes the {code}`info` function that gives us a quick summary of information about the component: +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 26-29 +---- +``` +The output will be of this form: +``` +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for NeuroMLDocument are: +* poisson_firing_synapses (class: PoissonFiringSynapse, Optional) +* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional) +* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional) +* alpha_current_synapses (class: AlphaCurrentSynapse, Optional) +* IF_curr_alpha (class: IF_curr_alpha, Optional) +* alpha_synapses (class: AlphaSynapse, Optional) +... +``` +This shows all the valid NeuroML components that the top level `NeuroMLDocument` component can directly contain. +It also tells us the component type (class) corresponding to the component (object). +It also tells us whether this component is optional or required. + +In the second form, where we also pass `show_contents=True`, it will also show the contents of each member if any. +We can use this to inspect our created Izhikevich cell component: +```{literalinclude} ./NML2_examples/izhikevich-single-neuron.py +---- +language: python +lines: 46 +---- +``` + +The output will be: +``` +Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for Izhikevich2007Cell are: +* annotation (class: Annotation, Optional) +* b (class: Nml2Quantity_conductance, Required) + * Contents ('ids'/): -2nS + +* c (class: Nml2Quantity_voltage, Required) + * Contents ('ids'/): -50.0mV + +* d (class: Nml2Quantity_current, Required) + * Contents ('ids'/): 100pA + +* C (class: Nml2Quantity_capacitance, Required) + * Contents ('ids'/): 100pF + +* v0 (class: Nml2Quantity_voltage, Required) + * Contents ('ids'/): -60mV + +* k (class: Nml2Quantity_conductancePerVoltage, Required) + * Contents ('ids'/): 0.7nS_per_mV + +* vr (class: Nml2Quantity_voltage, Required) + * Contents ('ids'/): -60mV + +* neuro_lex_id (class: NeuroLexId, Optional) +* metaid (class: MetaId, Optional) +* vt (class: Nml2Quantity_voltage, Required) + * Contents ('ids'/): -40mV + +* id (class: NmlId, Required) + * Contents ('ids'/): izh2007RS0 + +* notes (class: xs:string, Optional) +* vpeak (class: Nml2Quantity_voltage, Required) + * Contents ('ids'/): 35mV + +* properties (class: Property, Optional) +* a (class: Nml2Quantity_pertime, Required) + * Contents ('ids'/): 0.03per_ms +``` +We can see that all the required parameters are correctly set for this component. + +We can also inspect the full document: +```python +nml_doc.info(show_contents=True) +``` +Try running this at the beginning of the script right after creating the document, and at the end when the model has been completed. +You should notice a major change, that our cell has been correctly added to the document. +``` +... +* izhikevich2007_cells (class: Izhikevich2007Cell, Optional) +* * Contents ('ids'/): ['izh2007RS0'] +* +... +``` + +The `info()` function is very useful to see what components can belong to another. +For example, to see what components can be added to our `net` network, we can run this: +``` +net.info() + +Network -- Network containing: **population** s ( potentially of type **populationList** , and so specifying a list of cell **location** s ); **projection** s ( with lists of **connection** s ) and/or **explicitConnection** s; and **inputList** s ( with lists of **input** s ) and/or **explicitInput** s. Note: often in NeuroML this will be of type **networkWithTemperature** if there are temperature dependent elements ( e. g. ion channels ). + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for Network are: +* metaid (class: MetaId, Optional) +* notes (class: xs:string, Optional) +* properties (class: Property, Optional) +* annotation (class: Annotation, Optional) +* type (class: networkTypes, Optional) +* temperature (class: Nml2Quantity_temperature, Optional) +* neuro_lex_id (class: NeuroLexId, Optional) +* spaces (class: Space, Optional) +* regions (class: Region, Optional) +* extracellular_properties (class: ExtracellularPropertiesLocal, Optional) +* populations (class: Population, Required) +* cell_sets (class: CellSet, Optional) +* id (class: NmlId, Required) +* synaptic_connections (class: SynapticConnection, Optional) +* projections (class: Projection, Optional) +* electrical_projections (class: ElectricalProjection, Optional) +* continuous_projections (class: ContinuousProjection, Optional) +* explicit_inputs (class: ExplicitInput, Optional) +* input_lists (class: InputList, Optional) +``` +This tells us what `net` can contain. +For setting the input, for example, it would seem that we should use one of either `ExplicitInput` or `InputList` here. +The `ctinfo` function can be used to get more information about these (next). + +(userdocs:getting_started:single_example:supplementary:ctinfo)= +### The ctinfo() function + +There are multiple ways of getting information on a component type. +The first, of course, is to look at the {ref}`schema ` documentation online. +The documentation for ExplicitInput is {ref}`here `, and for InputList is {ref}`here `. +The schema documentation will also include examples of usage for most component types under the "Usage:Python" tab. + +`neuroml` includes the `ctinfo()` utility function, that like the `info()` method, provides information about component types (`ct` in `ctinfo` stands for `component type`). +Note that component types are classes and the `info()` method cannot be used on them. +It can only be used once objects have been created from the component type classes. + +So, we could do (create a new dummy object of the class and call `info()` on it): +```python +neuroml.ExplicitInput().info() +``` +but `ctinfo` will do this for us: +```python +from neuroml.utils import ctinfo +ctinfo("ExplicitInput") +# or the second form: +# ctinfo(neuroml.ExplicitInput) +ExplicitInput -- An explicit input ( anything which extends **basePointCurrent** ) to a target cell in a population + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for ExplicitInput are: +* destination (class: xs:string, Optional) +* target (class: xs:string, Required) +* input (class: xs:string, Required) + + +ctinfo("InputList") +InputList -- An explicit list of **input** s to a **population.** + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid members for InputList are: +* populations (class: NmlId, Required) +* component (class: NmlId, Required) +* input (class: Input, Optional) +* input_ws (class: InputW, Optional) +* id (class: NmlId, Required) +``` + +Finally, for completeness, we can also get information from the API documentation for libNeuroML [here](https://libneuroml.readthedocs.io/en/latest/). +Since this is documentation that is "embedded" in the Python classes, we can also use the Python [in-built help function](https://docs.python.org/3/library/functions.html#help) to see it: +``` +help(neuroml.ExplicitInput) +Help on class ExplicitInput in module neuroml.nml.nml: + +class ExplicitInput(BaseWithoutId) + | ExplicitInput(target: 'one str (required)' = None, input: 'one str (required)' = None, destination: 'one str (optional)' = None, gds_collector_=None, **kwargs_) + | + | ExplicitInput -- An explicit input ( anything which extends **basePointCurrent** ) to a target cell in a population + | + ... + + + +help(neuroml.InputList) +Help on class InputList in module neuroml.nml.nml: + +class InputList(Base) + | InputList(id: 'one NonNegativeInteger (required)' = None, populations: 'one NmlId (required)' = None, component: 'one NmlId (required)' = None, input: 'list of Input(s) (optional)' = None, input_ws: 'list of InputW(s) (optional)' = None, gds_collector_=None, **kwargs_) + | + | InputList -- An explicit list of **input** s to a **population.** + ... +``` + +The information provided by the different sources will be similar, but `ctinfo()` is perhaps the most NeuroML specific (whereas the Python `help()` function provides Python language related information also.) + + +```{admonition} Use an integrated development environment (IDE): +:class: tip +[IDEs](https://en.wikipedia.org/wiki/Comparison_of_integrated_development_environments#Python) make programming easier. For example, a good IDE will show you the documentation that the `help` Python function shows. +``` + +Another useful function is the `ctparentinfo()` function. +Like `info()` it provides some information about the component/object: +``` +ctparentinfo("InputList") +InputList -- An explicit list of **input** s to a **population.** + +Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information. + +Valid parents for InputList are: +* Network + * input_lists (class: InputList, Optional) +``` +This tells us that components of type `InputList` can be added to components of the `Network` type, in the `input_list` member. +Of course, we will use the `add` function in our network object `net`, and that will add the component to the correct member. + + +(userdocs:getting_started:single_example:supplementary:validate)= +### The validate() function + +We can check whether each component is valid using the `validate` function that each component has. +For example: +``` +net.validate() +``` +This function does not return anything if the component is valid. +(Technically, if a function does not return anything in Python, it returns +`None` by default, so this returns `None` if the component is valid.) +However, if it is not valid, it will throw a `ValueError`. + diff --git a/_sources/Userdocs/Software/MatLab.md b/_sources/Userdocs/Software/MatLab.md new file mode 100644 index 00000000..061b66e0 --- /dev/null +++ b/_sources/Userdocs/Software/MatLab.md @@ -0,0 +1,41 @@ +(matlab)= +# MatLab NeuroML Toolbox + +The NeuroML 2 Toolbox for MATLAB facilitates access to the Java NeuroML 2 API functionality ({ref}`jNeuroML `) directly within Matlab. + +(neuromlmatlab:quickstart)= +## Quick start + +Please install jNeuroML following the instructions provided {ref}`here `. +Run Matlab and run the `prefdir` command to find the location of your preferences folder. +Create a file `javaclasspath.txt` within that folder containing, on a single line, the full path to the `jNeuroML--jar-with-dependencies.jar` from jNeuroML. + +Restart Matlab, and you will be able to access jNeuroML classes. +You can test your setup by validating an example file: + +```{code-block} +import org.neuroml.model.util.NeuroML2Validator +file = java.io.File('/full/path/to/model.nml'); +validator = NeuroML2Validator(); +validator.validateWithTests(file); +disp(validator.getValidity()) +``` + +(neuromlmatlab:docs)= +## Documentation + +Please refer to the {ref}`jNeuroML documentation ` for information on the Java NeuroML API. +Examples on using the Matlab toolbox are available [here](https://github.com/NeuroML/NeuroMLToolbox/blob/master/examples/run_examples.m). + +(neuromlmatlab:gethelp)= +## Getting help + +For any questions regarding the NeuroML Matlab toolbix, please open an issue on the GitHub issue tracker [here](https://github.com/NeuroML/NeuroMLToolbox/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(neuromlmatlab:development)= +## Development + +The NeuroML Matlab toolbox is developed on GitHub at [https://github.com/NeuroML/NeuroMLToolbox](https://github.com/NeuroML/NeuroMLToolbox). diff --git a/_sources/Userdocs/Software/NeuroML_API.md b/_sources/Userdocs/Software/NeuroML_API.md new file mode 100644 index 00000000..bbd3acc6 --- /dev/null +++ b/_sources/Userdocs/Software/NeuroML_API.md @@ -0,0 +1,35 @@ +(neuromlc++)= +# NeuroML C++ API + +A C++ API for NeuroML. + +(neuromlc++:quickstart)= +## Quick start + +The C++ API is generated from the {ref}`NeuroML specification ` using the [CodeSynthesis XSD XML Schema to C++ data binding compiler](https://www.codesynthesis.com/products/xsd/). +The C++ API needs to be compiled from source. +Please refer to the instructions in the [Readme document](https://github.com/NeuroML/NeuroML_API/blob/master/README.md) for instructions on building and installing the API. + +(neuromlc++:docs)= +## Documentation + +For information on the generated C++ structure, please see the [XSD user manual](http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/). + +(neuromlc++:api_docs)= +### API documentation + +API documentation for the C++ API can be found [here](https://neuroml.github.io/NeuroML_API/). +It can also be generated while building the API from source, as documented in the [Readme](https://github.com/NeuroML/NeuroML_API/blob/master/README.md). + +(neuromlc++:gethelp)= +## Getting help + +For any questions regarding the C++ NeuroML API, please open an issue on the GitHub issue tracker [here](https://github.com/NeuroML/NeuroML_API/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(neuromlc++:development)= +## Development + +The C++ NeuroML API is developed on GitHub at [https://github.com/NeuroML/NeuroML_API](https://github.com/NeuroML/NeuroML_API) under the [MIT license](https://github.com/NeuroML/NeuroML_API/blob/master/License.txt). diff --git a/_sources/Userdocs/Software/NeuroMLlite.md b/_sources/Userdocs/Software/NeuroMLlite.md new file mode 100644 index 00000000..f26494cd --- /dev/null +++ b/_sources/Userdocs/Software/NeuroMLlite.md @@ -0,0 +1,137 @@ +(neuromllite)= +# NeuroMLlite + +NeuroMLlite is a common framework for reading/writing/generating network specifications which builds on NeuroML 2. +It is intended to provide a high level specification which can be used to generate networks in NeuroML and many other formats---including graphical and in neuronal simulator formats. + +```{admonition} Note: NeuroMLlite is under active development +:class: note dropdown +Please [watch the GitHub repository](https://github.com/NeuroML/NeuroMLlite) to receive regular updates on its progress. +``` + +(neuromllite:quickstart)= +## Quick start + +(neuromllite:install_python)= +### Install Python + +[Python](https://www.python.org/) is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official [installation instructions](https://www.python.org/downloads/) to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is [here](https://opensource.com/resources/python/ides). + +(neuromllite:install_with_pip)= +### Install NeuroMLlite with pip +```{admonition} Tip: Use a virtual environment +:class: tip dropdown + +While using Python packages, it is suggested to use a virtual environment to isolate the software you install from each other. +Learn more about using virtual environments in Python [here](https://docs.python.org/3/tutorial/venv.html). +``` + +The easiest way to install the latest version of libNeuroML is using the default Python package manager, `pip`: +```{code-block} console +pip install neuromllite +``` +(neuromllite:install_fedora)= +### Installation on Fedora Linux + +On [Fedora](https://getfedora.org) Linux systems, the [NeuroFedora](https://neuro.fedoraproject.org) community provides pyNeuroML as a package in their [extras repository](https://docs.fedoraproject.org/en-US/neurofedora/copr/) and can be installed using the following commands: + +```{code-block} console +sudo dnf copr enable @neurofedora/neurofedora-extra +sudo dnf install python3-neuromllite +``` + +(neuromllite:docs)= +## Documentation + +Along with a Python API, NeuroMLlite also provides a graphical user interface `nmllite-ui` that can be used to create network models and export or simulate them using different simulators supported by NeuroML. + +```{code-block} console +nmllite-ui + +NMLlite-UI v0.2.4: A GUI for loading NeuroMLlite files + +Usage: + nmllite-ui Sim_xxx.json + Load a NeuroMLlite file containing a Simulation, which refers to the Network to run +``` +```{figure} ../../images/nmllite-example.png +:alt: Screenshot of NeuroMLlite UI showing an example simulation. +:align: center + +Screenshot of NeuroMLlite UI showing an example simulation +``` + +(neuromllite:api_docs)= +### API documentation + +```{admonition} TODO! +:class: dropdown +Generate and publish API documentation for NeuroMLlite. +Issue filed: https://github.com/NeuroML/NeuroMLlite/issues/10 +``` +The NeuroMLlite API is self documented. +You can use Python's in-built documentation viewer `pydoc` to view the documentation for any of the package's modules and their functions: + +```{code-block} console +Help on package neuromllite: + +NAME + neuromllite + +PACKAGE CONTENTS + ArborHandler + BBPConnectomeReader + BaseTypes + ConnectivityHandler + DefaultNetworkHandler + GraphVizHandler + MatrixHandler + NetworkGenerator + NeuronHandler + PsyNeuLinkHandler + PsyNeuLinkReader + PyNNHandler + SonataHandler + SonataReader + gui (package) + sweep (package) + utils + +... +``` + +Most IDEs are able to show you this information as you use them in your Python scripts. + +A number of examples showing how the NeuroMLlite Python API is to be used are also included in the [GitHub repository](https://github.com/NeuroML/NeuroMLlite/tree/master/examples). +For instance, [Example4.py](https://github.com/NeuroML/NeuroMLlite/blob/master/examples/Example4.py) can be run in the following ways to generate different representations of the created network model. +Please see the [Readme file](https://github.com/NeuroML/NeuroMLlite/blob/master/README.md) included in the repository for more example usage. +```{code-block} console +python Example4.py # Generate the network in JSON +python Example4.py -nml # Generate the network in NeuroML2 +python Example4.py -jnml # Generate the network in NeuroML2 & run using jNeuroML +python Example4.py -jnmlnetpyne # Generate the network in NeuroML2 & run using NetPyNE +python Example4.py -jnmlnrn # Generate the network in NeuroML2 & run using NEURON +python Example4.py -netpyne # Generate & run the network directly in NetPyNE +python Example4.py -pynnnest # Generate & run the network in NEST using PyNN +python Example4.py -pynnnrn # Generate & run the network in NEURON using PyNN +python Example4.py -pynnbrian # Generate & run the network in Brian using PyNN +... +``` + +(neuromllite:gethelp)= +## Getting help + +For any questions regarding NeuroMLlite, please open an issue on the GitHub issue tracker [here](https://github.com/NeuroML/NeuroMLlite/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(neuromllite:development)= +## Development + +pyNeuroML is developed on GitHub at [https://github.com/NeuroML/NeuroMLlite](https://github.com/NeuroML/NeuroMLlite) under the [LPGL-3.0 license](https://github.com/NeuroML/NeuroMLlite/blob/master/LICENSE.lesser). +The repository contains the complete source code along with instructions on building/installing pyNeuroML. +Please follow the instructions there to build pyNeuroML from source. diff --git a/_sources/Userdocs/Software/Software.md b/_sources/Userdocs/Software/Software.md new file mode 100644 index 00000000..2df3bbf4 --- /dev/null +++ b/_sources/Userdocs/Software/Software.md @@ -0,0 +1,35 @@ +(userdocs:software)= +# Software and Tools + +## Core NeuroML Tools + +The NeuroML initiative supports **a core set of libraries** (mainly in Python and Java) to enable the creation/validation/analysis/simulation of NeuroML models as well as to facilitate adding support for the language to other applications. + +```{figure} ../../images/pynml_jnml.svg +:alt: jNeuroML and pyNeuroML +:align: center +:width: 500px + +Relationship between {ref}`jLEMS `, {ref}`jNeuroML `, the {ref}`NeuroML 2 LEMS definitions `, {ref}`libNeuroML `, {ref}`pyLEMS ` and {ref}`pyNeuroML `. + +``` + +### Python based applications + +For most users, {ref}`pyNeuroML ` will provide all of the key functionality for building, validating, simulating, visualising, and converting NeuroML 2 and LEMS models. It builds on {ref}`libNeuroML ` and {ref}`pyLEMS ` and bundles all of the functionality of {ref}`jNeuroML ` to provide access to this through a Python interface. + + +### Java based applications + +{ref}`jNeuroML ` (for validating, simulating and converting NeuroML 2 models) and {ref}`jLEMS ` (for simulating LEMS models) are the key applications +created in Java for supporting NeuroML 2/LEMS. + +### NeuroML support in other languages + +There are preliminary APIs for using NeuroML in {ref}`C++ ` and {ref}`MATLAB `. + +## Other NeuroML supporting applications + +Many other simulators, applications and libraries support NeuroML. See {ref}`here ` for more details. + +A number of databases and neuroinformatics initiatives support NeuroML as a core interchange format. See {ref}`here ` for more details. diff --git a/_sources/Userdocs/Software/SupportingTools.md b/_sources/Userdocs/Software/SupportingTools.md new file mode 100644 index 00000000..a2066674 --- /dev/null +++ b/_sources/Userdocs/Software/SupportingTools.md @@ -0,0 +1,373 @@ +(userdocs:supporting)= +# Tools and resources with NeuroML support + + +Apart from the **{ref}`core NeuroML tools `** (e.g. {ref}`pyNeuroML `, {ref}`jNeuroML `) there are many +other applications, libraries and databases which support NeuroML 2 and LEMS. + +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h + +These tools take a {ref}`number of different approaches ` to adding NeuroML support, from dealing with the format natively to allowing import/export of (subsets of) the language, to an external application generating scripts/code for use in the simulator. + +```{admonition} Please help us keep this page up to date. +:class: note + +Tools listed here may have moved to new locations, or may no longer be maintained, and others may be missing. +Please [file issues](https://github.com/NeuroML/Documentation/issues/new/choose) if you can help update this information. +``` + + + +(userdocs:supporting:apps)= +## Applications with NeuroML support + + +(userdocs:supporting:apps:neuron)= +### NEURON + +![NEURON logo](../../images/tools/neuron.png) + +The [NEURON] simulation environment is one of the main target platforms for a standard facilitating exchange of neuronal models. {ref}`jNeuroML ` can be used to convert NeuroML2/LEMS models to NEURON. NEURON simulations can also be generated from NeuroML model components by [neuroConstruct]. + +See also {ref}`NetPyNE `, which builds on NEURON. + +There is a **dedicated page on NEURON/NeuroML interactions** {ref}`here `. + + + +(userdocs:supporting:apps:netpyne)= +### NetPyNE + +![NetPyNE logo](../../images/tools/netpyne.png) + +[NetPyNE] is a Python package to facilitate the development, simulation, parallelization, analysis, and optimization of biological neuronal networks using the NEURON simulator. NetPyNE can import from and export to NeuroML. NetPyNE also provides a web based [Graphical User Interface](https://github.com/MetaCell/NetPyNE-UI/wiki). + +There is a **dedicated page on NetPyNE/NeuroML interactions** {ref}`here `. + +(userdocs:supporting:apps:neuroconstruct)= +### neuroConstruct + +![Neuroconstruct logo](../../images/tools/neuroconstruct.png) + +[neuroConstruct] is a Java based application for constructing 3D networks of biologically realistic neurons. The current version can generate code for the [NEURON], [GENESIS], [PSICS] and [PyNN] platforms and also provides import/export support for MorphML, ChannelML and NetworkML (from NeuroML v1) and for NeuroMLv2 cells and networks. + +More info on the support for NeuroML in neuroConstruct is available [here](http://www.neuroconstruct.org/docs/neuroml.html). + + + +(userdocs:supporting:apps:genesis)= +### GENESIS + +![GENESIS logo](../../images/tools/genesis.png) + +[GENESIS] is a commonly used neuronal simulation environment and was a main target platform for the NeuroMLv1 specifications. Full GENESIS simulations can be generated from NeuroMLv1 model components by [neuroConstruct]. + +Due to the lack of active development of GENESIS, support for mapping to GENESIS in NeuroMLv2 has been deprecated in favour of {ref}`MOOSE `. + +(userdocs:supporting:apps:moose)= +### MOOSE + +![MOOSE logo](../../images/tools/moose.jpg) + +[MOOSE] is the Multiscale Object-Oriented Simulation Environment. It is the base and numerical core for large, detailed multi-scale simulations that span computational neuroscience and systems biology. It is based on a complete reimplementation of the GENESIS 2 core. + +More information on running NeuroML models in MOOSE can be found {ref}`here `. + +There is a **dedicated page on MOOSE/NeuroML interactions** {ref}`here `. + + +(userdocs:supporting:apps:brian)= +### BRIAN + +![Brian logo](../../images/tools/brian2.png) + +[Brian] is an easy to use, Python based simulator of spiking networks. + +There is a **dedicated page on Brian/NeuroML interactions** {ref}`here `. + +(userdocs:supporting:apps:eden)= +### EDEN + +[EDEN] is a recently developed simulation engine which incorporates native NeuroML 2 support from the start. + +Initial tests of using EDEN with NeuroML models and example code can be found [here](https://github.com/OpenSourceBrain/EDENShowcase). + +There is a **dedicated page on EDEN/NeuroML interactions** {ref}`here `. + +(userdocs:supporting:apps:arbor)= +### Arbor + +![Arbor logo](../../images/tools/arbor.png) + +[Arbor] is a high performance multicompartmental neural simulation library. Addition of support for NeuroML2 and LEMS is under active development. +See [here](https://docs.arbor-sim.org/en/stable/fileformat/neuroml.html). + +Example code for interactions between NeuroML models and Arbor can be found [here](https://github.com/OpenSourceBrain/ArborShowcase). + +There is a **dedicated page on Arbor/NeuroML interactions** {ref}`here `. + +(userdocs:supporting:apps:pynn)= +### PyNN + +![PyNN logo](../../images/tools/pynn.png) + +[PyNN] is a Python package for simulator independent specification of neuronal network models. Model code can be developed using the PyNN API and then run using [NEURON], [NEST] or [Brian]. The developed model also can be stored as a NeuroML document. The latest version of [neuroConstruct] can be used to generate executable scripts for PyNN based simulators based on NeuroML components, although the majority of multicompartmental conductance based models which are available in neuroConstruct are outside the current scope of the PyNN API. + +More info on the latest support for running NeuroML models in PyNN and vice versa can be found [here](https://github.com/NeuroML/NeuroML2/issues/73). + +(userdocs:supporting:apps:nest)= +### NEST + +![NEST logo](../../images/tools/nest-logo.png) + +NEST is a simulator for spiking neural network models that focuses on the dynamics, size and structure of neural systems rather than on the exact morphology of individual neurons. + +There is a **dedicated page on NEST/NeuroML interactions** {ref}`here `. + +(userdocs:supporting:apps:openworm)= +### OpenWorm + +![OpenWorm logo](../../images/tools/openworm.png) + +The [OpenWorm] project aims to create a simulation platform to build digital in-silico living systems, starting with a C. elegans virtual organism simulation. The simulations and associated tools are being developed in a fully open source manner. NeuroML is being used for the description of the 302 neurons in the worm's nervous system, both for morphological description of the cells and their electrical properties. + +The [c302 subproject](https://github.com/openworm/c302) in OpenWorm has the latest developments in the NeuroML version of the worm nervous system. + + Members of the OpenWorm project are also creating a general purpose neuronal simulator (for both electrical and physical simulations) which will have parallelism and native support for NeuroML built in from the start (see {ref}`Geppetto `. + + + +(userdocs:supporting:apps:mdf)= +### Model Description Format (MDF) + +![MDF logo](../../images/tools/mdf.png) + +[ModECI Model Description Format (MDF)](https://github.com/ModECI/MDF) is an open source, community-supported standard and associated library of tools for expressing computational models in a form that allows them to be exchanged between diverse programming languages and execution environments, with a particular focus on machine learning, artificial intelligence and computational neuroscience. + +There will be full compatibility between NeuroML and MDF for specifying neuronal models. See [here](https://github.com/ModECI/MDF/blob/main/examples/NeuroML/README.md) for ongoing work in this direction. + +(userdocs:supporting:apps:tvb)= +### The Virtual Brain + +![TVB logo](../../images/tools/tvb.png) + +[The Virtual Brain (TVB)](https://www.thevirtualbrain.org) offers a simulation environment for large-scale brain networks. It allows network properties, in particular the brain’s structural connectivity, to be incorporated into models, and so TVB can simulate whole brain behaviour as is commonly observed in clinical scanners (e.g. EEG, MEG, fMRI). + +Initial work mapping networks in TVB to/from NeuroML 2 and LEMS can be found [here](https://github.com/OpenSourceBrain/TheVirtualBrainShowcase). See also the work of the [INCF Network Specification Working Group in this area](https://github.com/NeuralEnsemble/Networks_SIG/issues?q=is%3Aissue+is%3Aopen+label%3ATVB). + +(userdocs:supporting:apps:lfpy)= +### LFPy + +![LFPy logo](../../images/tools/lfpy.png) + +[LFPy] is a Python package for calculation of extracellular potentials from multicompartment neuron models. It relies on the NEURON simulator and uses the Python interface it provides. LFPy provides a set of easy to use Python classes for setting up the model, running simulations and calculating the extracellular potentials arising from activity in the model neuron. Initial support for loading of NeuroML morphologies has been added. + + +(userdocs:supporting:apps:biosimulators)= +### BioSimulators + +![BioSimulators logo](../../images/tools/biosimulators.png) + +[BioSimulators] provides a registry and platform supporting a broad range of modeling frameworks, model formats, simulation algorithms, and simulation tools. + +See for example https://biosimulators.org/simulators/pyneuroml/latest. + + +(userdocs:supporting:apps:N2A)= +### N2A + +"Neurons to Algorithms" (N2A) is a language for modeling neural systems, along with a software tool for editing models and simulating them. + +There is a **dedicated page on N2A/NeuroML interactions** {ref}`here `. + + +(userdocs:supporting:apps:neuronland)= +### NeuronLand + +![NeuronLand logo](../../images/tools/neuronland.png) + +[NeuronLand] provides NLMorphologyConverter, which is a command line program for converting between over 20 different 3D neuron morphology formats, and NLMorphologyViewer, which provides a simple interface for viewing these data. Both of these tools provide import and export of MorphML. + +(userdocs:supporting:apps:cx3d)= +### CX3D + +![CX3D logo](../../images/tools/cx3d.png) + +[CX3D] is a tool for simulating the growth of cortex in 3D. There was a preliminary implementation of export of generated networks to NeuroML in CX3D. + +(userdocs:supporting:apps:trees)= +### TREES toolbox + +![Trees logo](../../images/tools/trees.png) + +The [TREES toolbox] is an application in MATLAB which allows: automatic reconstruction of neuronal branching from microscopy image stacks and generation of synthetic axonal and dendritic trees; visualisation, editing and analysis of neuronal trees; comparison of branching patterns between neurons; and investigation of how dendritic and axonal branching depends on local optimization of total wiring and conduction distance. + +The latest version of the TREES toolbox includes basic functionality for exporting cells in NeuroML v1.x Level 1 (MorphML) or as a NeuroML v2alpha morphology file. + +(userdocs:supporting:apps:trackem)= +### TrakEM2 + +![TrakEM2 logo](../../images/tools/trakem2.png) + +[TrakEM2] is an ImageJ plugin for morphological data mining, three-dimensional modelling and image stitching, registration, editing and annotation. As of v0.8n, a menu item "Export - NeuroML..." gives an option to export to MorphML (the anatomy of the arbors only) or NeuroML (the whole network with anatomy and synapses), for the selected trees or all trees. + +(userdocs:supporting:apps:neurovisio)= +### Neuronvisio + +![Neuronvisio logo](../../images/tools/neuronvisio.png) + +[Neuronvisio] is a Graphical User Interface for NEURON simulator environment with 3D capabilities. Neuronvisio makes easy to select and investigate sections' properties, it offers easy integration with matplotlib for the plotting the results. It can save the geometry using NeuroML and the simulation results in a customised and extensible HDF5 format; the results can then be reload in the software and analysed at a later stage, without re-running the simulation. + + +(userdocs:supporting:apps:catmaid)= +### CATMAID + +![CATMAID logo](../../images/tools/catmaid.png) + +[CATMAID] is the Collaborative Annotation Toolkit for Massive Amounts of Image Data, and is a widely used tool for online reconstruction and annotation of connectomics data. Initial support for export of reconstructed neurons in NeuroML format has been added. + +(userdocs:supporting:apps:myokit)= +### Myokit + +![Myokit logo](../../images/tools/myokit.png) + +[Myokit] (the Maastricht Myocyte Toolkit) is a Python-based software package created by Michael Clerx to simplify the use of numerical models in the analysis of cardiac myocytes. Initial support for importing ChannelML [has been added](https://myokit.readthedocs.io/en/stable/api_formats/index.html#api-formats). + +(userdocs:supporting:apps:geppetto)= +### Geppetto + +![Geppetto logo](../../images/tools/geppetto.png) + +[Geppetto] is a web-based multi-algorithm, multi-scale simulation platform designed to support the simulation of complex biological systems and their surrounding environment. It is open source and is being developed as part of the {ref}`OpenWorm project ` to create an _in-silico_ model of the nematode _C. elegans_. It has had inbuilt support for NeuroML 2/LEMS from the start, and is suitable for many other types of neuronal models. + +(userdocs:supporting:other)= +## Other/legacy tools + +```{admonition} Older applications +Note: many of the applications listed below are no longer in active development or links no longer work. +``` + +(userdocs:supporting:other:psics)= +### PSICS + +The latest version of [neuroConstruct] can be used to generate executable scripts for [PSICS] based on NeuroML components. + +(userdocs:supporting:other:wbc)= +### Whole Brain Catalogue + +The [Whole Brain Catalog] was a graphical interface that allowed multiscale neuroscience data to be visualised relative to a 3D brain atlas. + +(userdocs:supporting:other:pcsim)= +### PCSIM +[PCSIM] is a tool in C++ for simulating large scale networks of cells and synapses. + +(userdocs:supporting:other:neuromantic)= +### Neuromantic +[Neuromantic] is a freeware tool for neuronal reconstruction (similar in some ways to part of Neurolucida's functionality). +Neuromantic mainly uses SWC/Cvapp format, but the latest version can import and export MorphML. + +(userdocs:supporting:other:neurospaces)= +### Neurospaces/ GENESIS 3 +The [Neurospaces/ GENESIS 3] project is developing a modular reimplementation of the core of GENESIS 2 along with a number of other components for computational neuroscience as part of the GENESIS 3 initiative. +Neurospaces/GENESIS 3 currently supports reading of passive models in NeuroML format (morphology + passive parameters). + +(userdocs:supporting:other:splitneuron)= +### SplitNeuron +[SplitNeuron] is a library written in C for data structures and functions extending SQLite to simulate large-scale networks of Izhikevich Simple Model compartments. +SplitNeuron answers a fundamental issue in large-scale simulation, data transfer between storage and functional software: it uses database not only for data storage but also as simulation engine, moving computation to data rather than using storage systems only for data holding. +This choice offers more features with less code to write and a unique way of accessing data for further analysis. +Features under development include direct import and cell/network creation from NeuroML. + +(userdocs:supporting:other:neuranim)= +### NeurAnim +[NeurAnim] is a research aid for computational neuroscience. +It is used to visualise and animate neural network simulations in 3D, and to render movies of these animations for use in presentations. +Networks stored in the instance based representation of NetworkML can be loaded and visualised. + +(userdocs:supporting:other:cnrun)= +### CNrun +[CNrun] is a neuronal network model simulator, similar in purpose to NEURON except that individual neurons are not compartmentalised. +It was built from refactored code written by Thomas Nowotny. +It reads in network topology description from a NeuroML file, where the cell_type attribute determines the unit class, one of the in-built neuron types of CNrun (e.g. Hodgkin Huxley cell by Traub and Miles (1991), Poisson oscillator, van der Pol oscillator). + +(userdocs:supporting:other:neugen)= +### NeuGen +[NeuGen] is an application in Java which is able to generate networks of synaptically connected morphologically detailed neurons, as in a cortical column. +NeuGen generates sets of neurons of the different morphological classes of the cortex, e.g. pyramidal cells and stellate neurons, and connects these networks in 3D. +The latest version of NeuGen can export the generated networks to NeuroML. +Some manual editing of the generated files is required to make them valid. +The developers have been informed of the required updates which will be incorporated soon. + +(userdocs:supporting:other:morphforge)= +### morphforge +[morphforge] is a high level, simulator independent, Python library for building simulations of small populations of multi-compartmental neurons. +It was built as part of the PhD thesis of Mike Hull (Uni. +Edinburgh): Investigating the role of electrical coupling in small populations of interneurons in Xenopus laevis tadpoles. +Loading of morphologies in MorphML format is supported, and loading of channel descriptions from ChannelML is in progress. +Future development of morphforge will be closely aligned with the development of the multicompartmental modelling API in Python (libNeuroML). + +(userdocs:supporting:other:neurotranslate)= +### NeuroTranslate +[NeuroTranslate] is a tool that translates input files between two different languages, the NCS (Neo-Cortical Simulator) input language and NeuroML format. +It provides a user-friendly interface, which can be used to both create and edit simulations. + +(userdocs:supporting:other:moogli)= +### Moogli +[Moogli] (a sister project of {ref}`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. +Loading of morphologies in MorphML and NeuroML formats is supported. + +[neuroConstruct]: http://www.neuroconstruct.org +[NEURON]: http://www.neuron.yale.edu/neuron/ +[NetPyNE]: http://netpyne.org/ +[GENESIS]: http://genesis-sim.org/ +[MOOSE]: https://moose.ncbs.res.in/ +[PSICS]: http://www.psics.org/index.html +[PyNN]: http://neuralensemble.org/PyNN/ +[NeuronLand]: http://neuronland.org/ +[PCSIM]: http://www.lsm.tugraz.at/pcsim/ +[CX3D]: http://www.ini.uzh.ch/~amw/seco/cx3d/ +[Neuromantic]: https://sourceforge.net/projects/neuromantic/ +[Neurospaces/ GENESIS 3]: http://neurospaces.sourceforge.net/ +[SplitNeuron]: https://sourceforge.net/projects/splitneuron/ +[Whole Brain Catalog]: https://twitter.com/braincatalog +[NeurAnim]: https://sourceforge.net/projects/neuranim/ +[CNrun]: http://johnhommer.com/academic/code/cnrun/ +[Trees toolbox]: https://github.com/cuntzlab/treestoolbox +[TrakEM2]: http://www.ini.uzh.ch/~acardona/trakem2.html +[Neuronvisio]: http://neuronvisio.org/ +[OpenWorm]: http://openworm.org/ +[NeuGen]: https://durus.gcsc.uni-frankfurt.de/~neugen/ +[LFPy]: https://lfpy.readthedocs.io/en/latest/ +[morphforge]: https://github.com/mikehulluk/morphforge +[NeuroTranslate]: https://github.com/nathanjordan/NeuroTranslate +[Moogli]: https://moose.ncbs.res.in/readthedocs/user/py/graphics/index_graphics.html +[CATMAID]: https://catmaid.readthedocs.io/en/stable/ +[Myokit]: http://myokit.org/ +[Neurovisio]: http://neuronvisio.org/ +[Geppetto]: http://www.geppetto.org/ +[NEST]: https://nest-simulator.org/ +[Brian]: https://briansimulator.org/ +[EDEN]: https://gitlab.com/neurocomputing-lab/Inferior_OliveEMC/eden +[Arbor]: https://arbor-sim.org/ +[BioSimulators]: https://biosimulators.org/ diff --git a/_sources/Userdocs/Software/Tools/Approaches.md b/_sources/Userdocs/Software/Tools/Approaches.md new file mode 100644 index 00000000..0162d1ed --- /dev/null +++ b/_sources/Userdocs/Software/Tools/Approaches.md @@ -0,0 +1,33 @@ +(userdocs:neuroml_support_approaches)= +# Approaches to adding NeuroML support + +There are a number of ways that a neuronal simulator can add "support for NeuroML", depending on how deeply it embeds/supports the elements of the language. + +## Commonly used approaches + +(userdocs:neuroml_support_approaches:native)= +### 1) Native support for NeuroML elements + +A simulator may have an equivalent internal representation of the core concepts from NeuroML2/LEMS, and so be able to natively read/write these formats. + +This is the approach taken in {ref}`jNeuroML ` and {ref}`EDEN `. + + +(userdocs:neuroml_support_approaches:native_import)= +### 2) Native ability to import NeuroML elements + +Another approach is for simulators to natively support importing (a subset of) NeuroML models, whereby the NeuroML components are converted to the equivalent entities in the simulator's internal representation of the model. + +This is the approach taken in {ref}`MOOSE `, {ref}`Arbor ` and {ref}`NetPyNE `. + +(userdocs:neuroml_support_approaches:native_export)= +### 3) Native ability to export NeuroML elements + +Some simulators allow models to be created with their preferred native model description format, and then exported in valid NeuroML. + +This is the approach taken in {ref}`NEURON ` and {ref}`NetPyNE `. It is also possible to export {ref}`PyNN ` models to NeuroML equivalents. + +(userdocs:neuroml_support_approaches:mapping)= +### 4) 3rd party mapping to simulator's own format + +This is the approach taken in {ref}`NEURON ` via {ref}`jNeuroML `. diff --git a/_sources/Userdocs/Software/Tools/Arbor.md b/_sources/Userdocs/Software/Tools/Arbor.md new file mode 100644 index 00000000..e49ab084 --- /dev/null +++ b/_sources/Userdocs/Software/Tools/Arbor.md @@ -0,0 +1,32 @@ +(userdocs:arbor)= +# Arbor and NeuroML + +![Arbor logo](../../../images/tools/arbor.png) + +[Arbor](https://arbor-sim.org/) is a high performance multicompartmental neural simulation library. Addition of support for NeuroML2 and LEMS is under active development. + +## Importing NeuroML into Arbor + +The current approach to supporting NeuroML in Arbor involves {ref}`importing NeuroML to Arbor's internal format `. + +See [here](https://docs.arbor-sim.org/en/stable/fileformat/neuroml.html) for Arbor's own documentation on this. It involves calling the [neuroml()](https://docs.arbor-sim.org/en/stable/python/morphology.html#arbor.neuroml) method in arbor pointing at the NeuroML file containing the cell you wish to load: + +```{code-block} python +nml = arbor.neuroml('mymorphology.cell.nml') + +``` +See [here](https://github.com/OpenSourceBrain/ArborShowcase/blob/main/NeuroML2/test_arbor.py) for a worked example of this, importing a multicompartmental cell with only a passive membrane conductance. + +### Support for channels/synapses in LEMS + +There is work under way to allow reading of the dynamics of ion channels and synapses which are specified in LEMS into Arbor. + +See https://github.com/thorstenhater/nmlcc for more details. + +## Network models in Arbor with NeuroMLlite + +There is preliminary support for building network specified in {ref}`NeuroMLlite ` format directly in Arbor. See [here](https://github.com/NeuroML/NeuroMLlite/tree/master/examples/arbor) for an example. + +## Examples + +Example code for interactions between NeuroML models and Arbor can be found in the [Arbor Showcase](https://github.com/OpenSourceBrain/ArborShowcase) repository. diff --git a/_sources/Userdocs/Software/Tools/Brian.md b/_sources/Userdocs/Software/Tools/Brian.md new file mode 100644 index 00000000..79fc4946 --- /dev/null +++ b/_sources/Userdocs/Software/Tools/Brian.md @@ -0,0 +1,31 @@ +(userdocs:brian)= +# Brian and NeuroML + +![Brian logo](../../../images/tools/brian2.png) + +[Brian](https://briansimulator.org/) is an easy to use, Python based simulator of spiking networks. + +## Converting NeuroML model to Brian + +{ref}`jNeuroML ` or {ref}`pyNeuroML ` can be used to convert NeuroML2/LEMS models to [Brian version 2](https://github.com/brian-team/brian2). This involves pointing at a {ref}`LEMS Simulation file ` describing what to simulate, and using the `-brian2` option: + +```{code-block} console +# Using jnml +jnml -brian2 + +# Using pynml +pynml -brian2 +``` + +This command generates a Python script (a file ending in `_brian2.py`) which can be run in Python and will simulate the model and plot/save the results, as outlined in the {ref}`LEMS Simulation file `. + +Notes: + +- Only single compartment cells can be converted to Brian format so far. While there is support in Brian for multicompartmental cell simulation, this is not yet covered in the jNeuroML based export. +- There has been support for converting NeuroML models to Brian v1 (using `-brian`), but since this version of Brian is deprecated, and only supports Python 2, this export is no longer actively developed. +- There is limited support for executing networks of cells in Brian, and the most likely route for adding this functionality is via {ref}`NeuroMLlite `. + + +## Examples + +Example code for interactions between NeuroML models and Brian can be found [here](https://github.com/OpenSourceBrain/BrianShowcase). diff --git a/_sources/Userdocs/Software/Tools/EDEN.md b/_sources/Userdocs/Software/Tools/EDEN.md new file mode 100644 index 00000000..870ff432 --- /dev/null +++ b/_sources/Userdocs/Software/Tools/EDEN.md @@ -0,0 +1,7 @@ +(userdocs:eden)= +# EDEN and NeuroML + + +[EDEN](https://gitlab.com/neurocomputing-lab/Inferior_OliveEMC/eden) is a recently developed simulation engine which incorporates native NeuroML 2 support from the start. + +Initial tests of using EDEN with NeuroML models and example code can be found [here](https://github.com/OpenSourceBrain/EDENShowcase). diff --git a/_sources/Userdocs/Software/Tools/MOOSE.md b/_sources/Userdocs/Software/Tools/MOOSE.md new file mode 100644 index 00000000..2b5f3349 --- /dev/null +++ b/_sources/Userdocs/Software/Tools/MOOSE.md @@ -0,0 +1,21 @@ +(userdocs:moose)= +# MOOSE and NeuroML + + +[MOOSE](https://moose.ncbs.res.in/) is the Multiscale Object-Oriented Simulation Environment. It is the base and numerical core for large, detailed multi-scale simulations that span computational neuroscience and systems biology. It is based on a complete reimplementation of the GENESIS 2 core. + +Some tests of using MOOSE with NeuroML models and example code can be found in the [MOOSE Showcase](https://github.com/OpenSourceBrain/MOOSEShowcase) repository. + + +## Simulating NeuroML models in MOOSE + + +You can export NeuroML models to the MOOSE simulator format using {ref}`jNeuroML ` or {ref}`pyNeuroML `, pointing at a {ref}`LEMS Simulation file ` describing what to simulate, and using the `-moose` option: + +```{code-block} console +# Using jnml +jnml -moose + +# Using pynml +pynml -moose +``` diff --git a/_sources/Userdocs/Software/Tools/N2A.md b/_sources/Userdocs/Software/Tools/N2A.md new file mode 100644 index 00000000..9da4383f --- /dev/null +++ b/_sources/Userdocs/Software/Tools/N2A.md @@ -0,0 +1,6 @@ +(userdocs:n2a)= +# N2A and NeuroML + +"Neurons to Algorithms" (N2A) is a language for modeling neural systems, along with a software tool for editing models and simulating them + +See [https://github.com/sandialabs/n2a/wiki/Backend%20LEMS](https://github.com/sandialabs/n2a/wiki/Backend%20LEMS) for information on the interactions between NeuroML/LEMS and N2A. diff --git a/_sources/Userdocs/Software/Tools/NEST.md b/_sources/Userdocs/Software/Tools/NEST.md new file mode 100644 index 00000000..48ce50cc --- /dev/null +++ b/_sources/Userdocs/Software/Tools/NEST.md @@ -0,0 +1,14 @@ +(userdocs:nest)= +# NEST and NeuroML + +![NEST logo](../../../images/tools/nest-logo.png) + +NEST is a simulator for spiking neural network models that focuses on the dynamics, size and structure of neural systems rather than on the exact morphology of individual neurons. The development of NEST is coordinated by the NEST Initiative. + +NEST is ideal for networks of spiking neurons of any size, for example: + +- Models of information processing e.g. in the visual or auditory cortex of mammals, +- Models of network activity dynamics, e.g. laminar cortical networks or balanced random networks, +- Models of learning and plasticity. + +See [https://github.com/OpenSourceBrain/NESTShowcase](https://github.com/OpenSourceBrain/NESTShowcase) for examples of usage of NeuroML and NEST. diff --git a/_sources/Userdocs/Software/Tools/NEURON.md b/_sources/Userdocs/Software/Tools/NEURON.md new file mode 100644 index 00000000..87d1f705 --- /dev/null +++ b/_sources/Userdocs/Software/Tools/NEURON.md @@ -0,0 +1,60 @@ +(userdocs:neuron)= +# NEURON and NeuroML + +![NEURON logo](../../../images/tools/neuron.png) + +[NEURON](http://www.neuron.yale.edu/neuron) is a widely used simulation environment and is one of the main target platforms for a standard facilitating exchange of neuronal models. + +(userdocs:neuron:simulating)= +## Simulating NeuroML models in NEURON + +{ref}`jNeuroML ` or {ref}`pyNeuroML ` can be used to convert NeuroML2/LEMS models to NEURON. This involves pointing at a {ref}`LEMS Simulation file ` describing what to simulate, and using the `-neuron` option: + +```{code-block} console +# Simulate the model using NEURON with python/hoc/mod files generated by jNeuroML +jnml -neuron -run + +# Simulate the model using NEURON with python/hoc/mod files generated by pyNeuroML +pynml -neuron -run +``` + +These commands generate a PyNeuron script and run it (a file ending in `_nrn.py`). +So you must have NEURON installed on your system, with its Python bindings (PyNeuron). +Skipping the `-run` flag will generate the Python script but will not run it: you can run it manually later. +Adding `-nogui` will suppress the NEURON graphical elements/menu opening and just run the model in NEURON in the background + +You can also run LEMS simulations using the NEURON simulator using the {ref}`pyNeuroML ` API: + +```{code-block} python +from pyneuroml.pynml import run_lems_with_jneuroml_neuron + +... + +run_lems_with_jneuroml_neuron(lems_file_name) +``` + +(userdocs:neuron:envvar)= +## Setting the NEURON_HOME environment variable + +Since it is possible to install multiple versions of NEURON in different places, the NeuroML tools need to be told where the NEURON tools are. +To do this, they look at the `NEURON_HOME` environment variable. +This needs to hold the path to where the binary (`bin`) folder holding the NEURON tools such as `nrniv` are located. +On Linux like systems, one can use `which` to find these tools and set the variable: + +``` {code-block} bash +$ which nrniv +~/.local/share/virtualenvs/neuroml-311-dev/bin/nrniv + +$ export NEURON_HOME="~/.local/share/virtualenvs/neuroml-311-dev/" +``` + +One can combine these commands together also: + +``` {code-block} bash +$ export NEURON_HOME="$(dirname $(dirname $(which nrniv)))" +``` + +(userdocs:neuron:neuroconstruct)= +## Using neuroConstruct + +NEURON simulations can also be generated from NeuroML model components by {ref}`neuroConstruct `, but most of this functionality is related to {ref}`NeuroML v1 `. diff --git a/_sources/Userdocs/Software/Tools/NetPyNE.md b/_sources/Userdocs/Software/Tools/NetPyNE.md new file mode 100644 index 00000000..65f90108 --- /dev/null +++ b/_sources/Userdocs/Software/Tools/NetPyNE.md @@ -0,0 +1,22 @@ +(userdocs:netpyne)= +# NetPyNE and NeuroML + +![NetPyNE logo](../../../images/tools/netpyne.png) + +[NetPyNE](http://netpyne.org) is a Python package to facilitate the development, simulation, parallelization, analysis, and optimization of biological neuronal networks using the NEURON simulator. NetPyNE can import from and export to NeuroML. NetPyNE also provides a web based [Graphical User Interface](https://github.com/MetaCell/NetPyNE-UI/wiki). + +## Importing NeuroML into NetPyNE + +An example of how to import a network in NeuroML into NetPyNE can be found [here](https://github.com/Neurosim-lab/netpyne/blob/development/examples/NeuroMLImport/SimpleNet_import.py). + +## Exporting NeuroML from NetPyNE + +An example of how to export a network built using NetPyNE to NeuroML can be found [here](https://github.com/OpenSourceBrain/NetPyNEShowcase/blob/master/NetPyNE/HHSmall/HH_export.py). + +## Running NetPyNE on OSBv2 + +Building and running NetPyNE models will be a core feature of Open Source Brain v2.0. See [here](https://docs.opensourcebrain.org/OSBv2/NetPyNE.html) for more details. + +## NeuroMLlite + +NetPyNE is also a key target for cross simulator network creation using {ref}`NeuroMLlite `. There are ongoing plans for greater alignment between formats used for network specification in NetPyNE and NeuroMLlite. diff --git a/_sources/Userdocs/Software/Tools/PyNN.md b/_sources/Userdocs/Software/Tools/PyNN.md new file mode 100644 index 00000000..9a20e59d --- /dev/null +++ b/_sources/Userdocs/Software/Tools/PyNN.md @@ -0,0 +1,15 @@ +(userdocs:pynn)= +# PyNN and NeuroML + +![PyNN logo](../../../images/tools/pynn.png) + + +[PyNN](http://neuralensemble.org/PyNN/) is a Python package for simulator independent specification of neuronal network models. Model code can be developed using the PyNN API and then run using [NEURON](http://www.neuron.yale.edu/neuron/), [NEST](https://nest-simulator.org/) or [Brian](https://briansimulator.org/). The developed model also can be stored as a NeuroML document. + +The latest version of {ref}`neuroConstruct ` can be used to generate executable scripts for PyNN based simulators based on NeuroML components, although the majority of multicompartmental conductance based models which are available in neuroConstruct are outside the current scope of the PyNN API. + +See [https://github.com/OpenSourceBrain/PyNNShowcase](https://github.com/OpenSourceBrain/PyNNShowcase) for examples of usage of NeuroML and PyNN. + +More info on the latest support for running NeuroML models in PyNN and vice versa can be found [here](https://github.com/NeuroML/NeuroML2/issues/73). + +PyNN is also a key target for cross simulator network creation using {ref}`NeuroMLlite `. diff --git a/_sources/Userdocs/Software/jLEMS.md b/_sources/Userdocs/Software/jLEMS.md new file mode 100644 index 00000000..ebe1e41f --- /dev/null +++ b/_sources/Userdocs/Software/jLEMS.md @@ -0,0 +1,36 @@ +(jlems)= +# jLEMS + +jLEMS is an interpreter for the Low Entropy Model Specification language written in Java. +```{admonition} jLEMS is the reference implementation of LEMS +:class: dropdown +jLEMS was developed by Robert Cannon when the LEMS language was being devised and serves at the key reference for how to implement/interpret the language. +``` + +(jlems:quickstart)= +## Quick start + +Since jLEMS is included in {ref}`jNeuroML `, it does need not to be installed it separately. +Please follow the instructions on installing jNeuroML provided {ref}`here `. + +Please see the {ref}`development section below ` for information on building the jLEMS interpreter from source. + +(jlems:docs)= +## Documentation + +Detailed documentation on LEMS is maintained [here](http://lems.github.io/LEMS/). +For more information on LEMS, please also see Cannon et al. ({cite}`Cannon2014`) + +(jlems:gethelp)= +## Getting help + +For any questions regarding jLEMS, please open an issue on the GitHub issue tracker [here](https://github.com/LEMS/jLEMS/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(jlems:development)= +## Development + +jLEMS is developed on GitHub at [https://github.com/LEMS/jLEMS](https://github.com/LEMS/jLEMS) under the [MIT license](https://github.com/LEMS/jLEMS/blob/master/LICENSE). +The repository contains the complete source code along with instructions on building/installing jLEMS. diff --git a/_sources/Userdocs/Software/jNeuroML.md b/_sources/Userdocs/Software/jNeuroML.md new file mode 100644 index 00000000..b788c763 --- /dev/null +++ b/_sources/Userdocs/Software/jNeuroML.md @@ -0,0 +1,123 @@ +(jneuroml)= +# jNeuroML + +jNeuroML is a Free/Open Source Java tool for working with LEMS and NeuroML 2. +It includes the `jnml` command line application, and can also be used as a Java library. + +With jNeuroML you can: + +- **Validate** NeuroML v1.8.1 and v2.x files +- **Simulate** NeuroML 2 models +- **Export** NeuroML 2 and LEMS files to many formats such as Neuron, Brian, Matlab, etc. +- **Import** other languages into LEMS (e.g. SBML) +- **Visualise** NeuroML models and simulations + +```{admonition} Use pyNeuroML +:class: dropdown +{ref}`pyNeuroML ` builds on jNeuroML and includes additional functions. +``` +(jneuroml:quickstart)= +## Quick start + +(jneuroml:install_java)= +### Install the Java Runtime Environment + +Since jNeuroML is written in Java, you will need a Java Runtime Environment (JRE) installed on your system. +On most Linux systems [Free/Open source OpenJDK runtime environment](https://openjdk.java.net/) is already pre-installed. +You can also install Oracle's proprietary Java platform from their [download page](https://www.oracle.com/java/technologies/javase-downloads.html) if you prefer. +Please refer to your operating system's documentation to install a JRE. + +(jneuroml:install_jar)= +### Installation using pre-compiled JAR + +jNeuroML is provided as a pre-compiled ready-to-use Java JAR file that can be used on any computer that has Java installed. +Please download it from the [GitHub release page](https://github.com/NeuroML/jNeuroML/releases) and unzip (extract) it in a preferred folder on your computer: + +```{code-block} console +cd +unzip jNeuroML.zip +``` +This will extract the zip file to a new folder which will contain the pre-compiled JAR file and runner scripts: + +```{code-block} console +ls jNeuroMLJar/ +jNeuroML-0.10.2-jar-with-dependencies.jar jnml jnml.bat README +``` + +```{admonition} TODO +:class: dropdown +Add instructions on using the installer script. +https://github.com/NeuroML/jNeuroML/pull/76 +``` + +(jneuroml:install_fedora)= +### Installation on Fedora Linux + +On [Fedora](https://getfedora.org) Linux systems, the [NeuroFedora](https://neuro.fedoraproject.org) community provides jNeuroML as a package in their [extras repository](https://docs.fedoraproject.org/en-US/neurofedora/copr/) and can be installed using the following commands: + +```{code-block} console +sudo dnf copr enable @neurofedora/neurofedora-extra +sudo dnf install jneuroml +``` + +(jneuroml:docs)= +## Documentation + +Information on usage of the `jnml` command line application can be found with the -h option: + +```{code-block} console +jnml -h + + jNeuroML v0.10.1 +Usage: + + jnml LEMSFile.xml + Load LEMSFile.xml using jLEMS, parse it and validate it as LEMS, and execute the model it contains + + jnml LEMSFile.xml -nogui + As above, parse and execute the model and save results, but don't show GUI + + ... +``` +(jneuroml:api_docs)= +### API documentation + +The jNeuroML API is self documented. +Please refer to the various packages to learn their usage: + +- [NeuroML/jNeuroML](https://github.com/NeuroML/jNeuroML) (API Documentation [here](http://neuroml.github.io/jNeuroML)) +- [NeuroML/org.neuroml.model](https://github.com/NeuroML/org.neuroml.model) (API Documentation [here](http://neuroml.github.io/org.neuroml.model/index.html)) +- [NeuroML/org.neuroml.model.injectingplugin](https://github.com/NeuroML/org.neuroml.model.injectingplugin) (API Documentation [here](http://neuroml.github.io/org.neuroml.model.injectingplugin/index.html)) +- [NeuroML/org.neuroml.import: Import other formats into LEMS & combine with NeuroML models](https://github.com/NeuroML/org.neuroml.import) (API documentation [here](http://neuroml.github.io/org.neuroml.import/)) +- [NeuroML/org.neuroml.export: Export from NeuroML & LEMS](https://github.com/NeuroML/org.neuroml.export) (API Documentation [here](http://neuroml.github.io/org.neuroml.export/index.html)) + +(jneuroml:gethelp)= +## Getting help + +For any questions regarding jNeuroML, please open an issue on the GitHub issue tracker [here](https://github.com/NeuroML/jNeuroML/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(jneuroml:development)= +## Development + +jNeuroML is developed on GitHub at [https://github.com/NeuroML/jNeuroML](https://github.com/NeuroML/jNeuroML) under the [LPGL-3.0 license](https://github.com/NeuroML/jNeuroML/blob/master/LICENSE.lesser). +The repository contains the complete source code along with instructions on building/installing jNeuroML. +Please follow the instructions there to build jNeuroML from source. + +(jneuroml:nightlies)= +### Nightly (pre-release) jar builds: + +```{warning} +Please note that these JARs are considered experimental and should only be used for testing purposes. +``` + +In case you want to use a development (un-released) version of jNeuroML, you can download a development build following the steps below. +You will need to have the [Subversion](https://subversion.apache.org/) tool installed on your system. + +```{code-block} console +svn checkout svn://svn.code.sf.net/p/neuroml/code/jNeuroMLJar +cd jNeuroMLJar +``` + diff --git a/_sources/Userdocs/Software/libNeuroML.md b/_sources/Userdocs/Software/libNeuroML.md new file mode 100644 index 00000000..95482e9c --- /dev/null +++ b/_sources/Userdocs/Software/libNeuroML.md @@ -0,0 +1,104 @@ +(libneuroml)= +# libNeuroML + +libNeuroML is a Python package for working with models specified in NeuroML version 2. +It provides a native Python object model corresponding to the NeuroML schema. +This allows users to build their NeuroML models natively in Python without having to work directly with the underlying XML representation. +Additionally, libNeuroML includes functions for the conversion of the Python representation of the NeuroML model to and from the XML representation. + +```{admonition} Use pyNeuroML +:class: dropdown +{ref}`pyNeuroML ` builds on libNeuroML and includes additional utility functions. +``` +```{admonition} Citation +:class: dropdown +Please cite Vella et al. ({cite}`Vella2014`) if you use libNeuroML. +``` + +(libneuroml:quickstart)= +## Quick start + +(libneuroml:install_python)= +### Install Python + +[Python](https://www.python.org/) is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official [installation instructions](https://www.python.org/downloads/) to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is [here](https://opensource.com/resources/python/ides). + +(libneuroml:install_with_pip)= +### Install libNeuroML with pip +```{admonition} Tip: Use a virtual environment +:class: tip dropdown + +While using Python packages, it is suggested to use a virtual environment to isolate the software you install from each other. +Learn more about using virtual environments in Python [here](https://docs.python.org/3/tutorial/venv.html). +``` + +The easiest way to install the latest version of libNeuroML is using the default Python package manager, `pip`: +```{code-block} console +pip install libNeuroML +``` +(libneuroml:install_fedora)= +### Installation on Fedora Linux + +On [Fedora](https://getfedora.org) Linux systems, the [NeuroFedora](https://neuro.fedoraproject.org) community provides libNeuroML in the [standard Fedora repos](https://src.fedoraproject.org/rpms/python-libNeuroML) and can be installed using the following commands: + +```{code-block} console +sudo dnf install python3-libNeuroML +``` +(libneuroml:docs)= +## Documentation + +Detailed API documentation for libNeuroML can be found [here](https://libneuroml.readthedocs.io/en/latest/). +For more information on libNeuroML, please see Vella et al. ({cite}`Vella2014`) and Cannon et al. ({cite}`Cannon2014`). + +The core classes in NeuroML are Python representations of the Component Types defined in the {ref}`NeuroML standard `. +These can be used to build NeuroML models in Python, and these models can then be exported to the standard XML NeuroML representation. +These core classes also contain some utility functions to make it easier for users to carry out common tasks. + +```{figure} ../../images/libneuroml.png +:alt: Examples of mapping between Component names in the NeuroML schema and their corresponding libNeuroML Python classes. +:align: center + +Examples of mapping between Component names in the NeuroML schema and their corresponding libNeuroML Python classes. +``` + +Each NeuroML Component Type is represented here as a Python class. +Due to implementation limitations, whereas NeuroML Component Types use [lower camel case naming](https://en.wikipedia.org/wiki/Camel_case), the Python classes here use [upper camel case naming](https://en.wikipedia.org/wiki/Camel_case). +So, for example, the `adExIaFCell` Component Type in the NeuroML schema becomes the `AdExIaFCell` class here, and `expTwoSynapse` becomes the `ExpTwoSynapse` class. + +The `child` and `children` elements that NeuroML Component Types can have are represented in the Python classes as variables. +The variable names, to distinguish them from class names, use [snake case](https://en.wikipedia.org/wiki/Snake_case). +So for example, the `cell` NeuroML Component Type has a corresponding `Cell` Python class here. +The `biophysicalProperties` child Component Type in `cell` is represented as the `biophysical_properties` list variable in the `Cell` Python class. +The class signatures list all the child/children elements and text fields that the corresponding Component Type possesses. +To again use the `Cell` class as an example, the construction signature is this: + +```{code-block} python +class neuroml.nml.nml.Cell(neuro_lex_id=None, id=None, metaid=None, notes=None, properties=None, annotation=None, morphology_attr=None, biophysical_properties_attr=None, morphology=None, biophysical_properties=None, extensiontype_=None, **kwargs_) +``` +As can be seen here, it includes both the `biophysical_properties` and `morphology` child elements as variables. + +Please see the examples in the {ref}`NeuroML documentation ` to see usage examples of libNeuroML. +Please also note that this module is also included in the top level of the `neuroml` package, so you can use these classes by importing neuroml: + +```{code-block} python +from neuroml import AdExIaFCell +``` + + +(libneuroml:gethelp)= +## Getting help + +For any questions regarding libNeuroML, please open an issue on the GitHub issue tracker [here](https://github.com/NeuralEnsemble/libNeuroML/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(libneuroml:development)= +## Development + +libNeuroML is developed on GitHub at [https://github.com/NeuralEnsemble/libNeuroML](https://github.com/NeuralEnsemble/libNeuroML) under the [BSD 3 clause license](https://github.com/NeuralEnsemble/libNeuroML/blob/master/LICENSE). +The repository contains the complete source code along with instructions on building/installing libNeuroML. +Please follow the instructions there to build libNeuroML from source. diff --git a/_sources/Userdocs/Software/pyLEMS.md b/_sources/Userdocs/Software/pyLEMS.md new file mode 100644 index 00000000..bdaf8295 --- /dev/null +++ b/_sources/Userdocs/Software/pyLEMS.md @@ -0,0 +1,137 @@ +(pylems)= +# pyLEMS + +pyLEMS is a Python package which provides an API, as well as a simulator for the [LEMS](http://lems.github.io/LEMS) language. +It can also be used to run NeuroML2 models. +```{admonition} Use pyNeuroML +:class: dropdown +{ref}`pyNeuroML ` builds on pyLEMS and includes additional functions. +``` + +```{admonition} Citation +:class: dropdown +Please cite Vella et al. ({cite}`Vella2014`) if you use pyLEMS. +``` + +(pylems:quickstart)= +## Quick start + +(pylems:install_python)= +### Install Python + +[Python](https://www.python.org/) is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official [installation instructions](https://www.python.org/downloads/) to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is [here](https://opensource.com/resources/python/ides). + +(pylems:install_with_pip)= +### Install pyLEMS with pip +```{admonition} Tip: Use a virtual environment +:class: tip dropdown + +While using Python packages, it is suggested to use a virtual environment to isolate the software you install from each other. +Learn more about using virtual environments in Python [here](https://docs.python.org/3/tutorial/venv.html). +``` + +The easiest way to install the latest version of pyLEMS is using the default Python package manager, `pip`: +```{code-block} console +pip install pyLEMS +``` +(pylems:install_fedora)= +### Installation on Fedora Linux + +On [Fedora](https://getfedora.org) Linux systems, the [NeuroFedora](https://neuro.fedoraproject.org) community provides pyLEMS in the [standard Fedora repos](https://src.fedoraproject.org/rpms/python-pyLEMS) and can be installed using the following commands: + +```{code-block} console +sudo dnf install python3-pyLEMS +``` +(pylems:docs)= +## Documentation + +Detailed API documentation for PyLEMS can be found [here](https://pylems.readthedocs.io/en/development/). +pyLEMS provides the `pylems` command line utility that can be used to simulate LEMS files. +`pylems` is self documented, and you can learn about its usage using the `-h` flag: + +```{code-block} console +pylems -h +usage: pylems [-h] [-I ] [-nogui] [-dlems] + +positional arguments: + LEMS file to be simulated + +optional arguments: + -h, --help show this help message and exit + -I + Directory to be searched for included files + -nogui If this is specified, just parse & simulate the model, but don't show any plots + -dlems If this is specified, export the LEMS file as dLEMS (distilled LEMS in JSON format, see https://github.com/borismarin/som-codegen) +``` + +To simulate a LEMS file: + +```{code-block} console +pylems lemsexample.xml + +``` +Please note that if you are simulating a NeuroML file you will have to also specify the location of the {ref}`NeuroML 2 LEMS definitions ` with the `-I` option. +We suggest that you use {ref}`pyNeuroML ` where this is not required: +```{code-block} console +pylems -I /NeuroML2CoreTypes/ LEMS_NeuroML2_Model.xml +``` + +For more information on pyLEMS, please see Vella et al. ({cite}`Vella2014`) and Cannon et al. ({cite}`Cannon2014`). + +(pylems:api_docs)= +### API documentation + +Detailed API documentation for pyNeuroML can be found [here](https://pylems.readthedocs.io/en/development/index.html). + +The pyLEMS API is also self documented. +You can use Python's in-built documentation viewer `pydoc` to view the documentation for any of the package's modules and their functions: + +```{code-block} console +Help on package lems: + +NAME + lems + +DESCRIPTION + @author: Gautham Ganapathy + @organization: LEMS (http://neuroml.org/lems/, https://github.com/organizations/LEMS) + @contact: gautham@lisphacker.org + +PACKAGE CONTENTS + api + base (package) + dlems (package) + model (package) + parser (package) + run + sim (package) + +DATA + logger = + +VERSION + 0.5.2 + +FILE + /usr/lib/python3.9/site-packages/lems/__init__.py + +``` +Most IDEs are able to show you this information as you use them in your Python scripts. + +(pylems:gethelp)= +## Getting help + +For any questions regarding pyLEMS, please open an issue on the GitHub issue tracker [here](https://github.com/LEMS/pylems/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(pylems:development)= +## Development + +pyLEMS is developed on GitHub at [https://github.com/LEMS/pylems](https://github.com/LEMS/pylems) under the [LGPL-3.0 license](https://github.com/LEMS/pylems/blob/master/LICENSE.lesser). +The repository contains the complete source code along with instructions on building/installing pyLEMS. +Please follow the instructions there to build pyLEMS from source. diff --git a/_sources/Userdocs/Software/pyNeuroML.md b/_sources/Userdocs/Software/pyNeuroML.md new file mode 100644 index 00000000..408e6109 --- /dev/null +++ b/_sources/Userdocs/Software/pyNeuroML.md @@ -0,0 +1,233 @@ +(pyneuroml)= +# pyNeuroML + +```{admonition} Suggested NeuroML tool +:class: dropdown +pyNeuroML is the suggested software tool for working with NeuroML. +It builds on {ref}`jNeuroML `, {ref}`libNeuroML `, and {ref}`pyLEMS `. +``` +```{admonition} Citation +:class: dropdown +Please cite Vella et al. ({cite}`Vella2014`) if you use pyNeuroML. +``` + +pyNeuroML is a Python package that allows you to work with NeuroML models using the Python programming language. +It includes all the API functions provided by {ref}`libNeuroML ` and {ref}`pyLEMS `, and also wraps all the functions that {ref}`jNeuroML ` provides, which can therefore be used from within Python itself. + +With pyNeuroML you can: + +- **Create** NeuroML models and simulations +- **Validate** NeuroML v1.8.1 and v2.x files +- **Simulate** NeuroML 2 models +- **Export** NeuroML 2 and LEMS files to many formats such as Neuron, Brian, Matlab, etc. +- **Import** other languages into LEMS (e.g. SBML) +- **Visualise** NeuroML models and simulations + +```{figure} ../../images/pynml_jnml.svg +:alt: jNeuroML and pyNeuroML +:align: center +:width: 500px + +Relationship between {ref}`jLEMS `, {ref}`jNeuroML `, the {ref}`NeuroML 2 LEMS definitions `, {ref}`libNeuroML `, {ref}`pyLEMS ` and {ref}`pyNeuroML `. + +``` + +(pyneuroml:quickstart)= +## Quick start + +(pyneuroml:install_python_and_java)= +### Install Python and the Java Runtime Environment + +[Python](https://www.python.org/) is generally pre-installed on all computers nowadays. +However, if you do not have Python installed on your system, please follow the official [installation instructions](https://www.python.org/downloads/) to install Python on your computer. +A number of Free/Open source Integrated Development Environments (IDEs) are also available that make working with Python (even) easier. +An example list is [here](https://opensource.com/resources/python/ides). + +Since pyNeuroML wraps around jNeuroML which is written in Java, you will need a Java Runtime Environment (JRE) installed on your system. +On most Linux systems [Free/Open source OpenJDK runtime environment](https://openjdk.java.net/) is already pre-installed. +You can also install Oracle's proprietary Java platform from their [download page](https://www.oracle.com/java/technologies/javase-downloads.html) if you prefer. +Please refer to your operating system's documentation to install a JRE. + +(pyneuroml:install_with_pip)= +### Install pyNeuroML with pip + +```{admonition} Tip: Use a virtual environment +:class: tip dropdown + +While using Python packages, it is suggested to use a virtual environment to isolate the software you install from each other. +Learn more about using virtual environments in Python [here](https://docs.python.org/3/tutorial/venv.html). +``` + +The easiest way to install the latest version of pyNeuroML is using the default Python package manager, `pip`: + +```{code-block} console +pip install pyneuroml +``` + +By default, this will only install the minimal set of packages required to use pyNeuroML. +To use pyNeuroML with specific {ref}`supporting tools `, please install them as required: + +```{code-block} console +pip install pyneuroml[neuron] # for NEURON simulation backend +pip install pyneuroml[brian] # for Brian2 simulation backend +pip install pyneuroml[netpyne] # for NetPyNE simulation backend +pip install pyneuroml[povray] # for povray functions +pip install pyneuroml[hdf5] # for HDF5 support +pip install pyneuroml[analysis] # for analysis functions +pip install pyneuroml[tune] # for tuning/fitting functions +pip install pyneuroml[vispy] # for 3D interactive morphology plotting using vispy +pip install pyneuroml[plotly] # for interactive plotting with plotly +pip install pyneuroml[nsg] # pulls in pynsgr to use NSG +pip install pyneuroml[combine] # includes libsbml, libsedml +pip install pyneuroml[tellurium] # for Tellurium simulation backend +pip install pyneuroml[all] # installs all of the above +pip install pyneuroml[dev] # installs the above and other test related packages +pip install pyneuroml[doc] # for building documentation +``` + +Please note that for compiling NEURON mod files, you also need a C compiler and the `make` utility installed on your computer. +Additionally, to run parallel simulations the [MPI](https://en.wikipedia.org/wiki/Message_Passing_Interface) libraries are also needed. +Please see the [NEURON installation documentation](https://www.neuron.yale.edu/neuron/download) for more information on installing NEURON on your computer. + +For more information on individual simulation backends, please refer to their respective documentations. + +(pyneuroml:install_fedora)= +### Installation on Fedora Linux + +On [Fedora](https://getfedora.org) Linux systems, the [NeuroFedora](https://neuro.fedoraproject.org) community provides pyNeuroML as a package in their [extras repository](https://docs.fedoraproject.org/en-US/neurofedora/copr/) and can be installed using the following commands: + +```{code-block} console +sudo dnf copr enable @neurofedora/neurofedora-extra +sudo dnf install python3-pyneuroml +``` + +Optional packages can also be installed using the default package manager: + +``` +sudo dnf install python3-brian2 python3-neuron neuron-devel python3-netpyne +``` + +MPI builds of these tools are also available in the NeuroFedora repositories. +Please see the [project documentation](https://docs.fedoraproject.org/en-US/neurofedora/mpi/) on installing and using them. + +(pyneuroml:docs)= +## Documentation + +pyNeuroML provides a set of command line utilities along with an API to use from within Python scripts: + +```{admonition} TODO! +:class: dropdown +Check that all of these have usage documentation that is viewable using the `-h` flag. +Issue filed: https://github.com/NeuroML/pyNeuroML/issues/87 +``` + +- pynml +- pynml-channelanalysis +- pynml-modchananalysis +- pynml-plotspikes +- pynml-povray +- pynml-sonata +- pynml-summary +- pynml-tune + +These utilities are self-documented. +So, to learn how these utilities are to be used, run them with the `-h` flag. +For example: + +```{code-block} console +pynml -h +usage: pynml [-h|--help] [] + +pyNeuroML v0.5.9: Python utilities for NeuroML2 + libNeuroML v0.2.54 + jNeuroML v0.10.2 + +optional arguments: + -h, --help show this help message and exit + +Shared options: + These options can be added to any of the mutually-exclusive options + + -verbose Verbose output + -java_max_memory MAX Java memory for jNeuroML, e.g. 400M, 2G (used in + -Xmx argument to java) + -nogui Suppress GUI, + i.e. show no plots, just save results + + LEMS/NeuroML 2 file to process + +... +``` +(pyneuroml:api_docs)= +### API documentation + +Detailed API documentation for pyNeuroML can be found [here](https://pyneuroml.readthedocs.io/en/development/). + +The pyNeuroML API is also self documented. +You can use Python's in-built documentation viewer `pydoc` to view the documentation for any of the package's modules and their functions: +```{code-block} console + +pydoc pyneuroml +Help on package pyneuroml: + +NAME + pyneuroml + +PACKAGE CONTENTS + analysis (package) + lems (package) + neuron (package) + plot (package) + povray (package) + pynml + swc (package) + tune (package) + +DATA + JNEUROML_VERSION = '0.10.2' + +VERSION + 0.5.9 + +FILE + /usr/lib/python3.9/site-packages/pyneuroml/__init__.py + +``` +```{code-block} console +pydoc pyneuroml.analysis + +Help on package pyneuroml.analysis in pyneuroml: + +NAME + pyneuroml.analysis + +PACKAGE CONTENTS + ChannelDensityPlot + ChannelHelper + NML2ChannelAnalysis + +FUNCTIONS + analyse_spiketime_vs_dt(nml2_file, target, duration, simulator, cell_v_path, dts, verbose=False, spike_threshold_mV=0, show_plot_already=True, save_figure_to=None, num_of_last_spikes=None) + + generate_current_vs_frequency_curve(nml2_file, cell_id, start_amp_nA=-0.1, end_amp_nA=0.1, step_nA=0.01, custom_amps_nA=[], analysis_duration=1000, analysis_delay=0, pre_zero_pulse=0, post_zero_pulse=0, dt=0.05, temperature='32degC', spike_threshold_mV=0.0, plot_voltage_traces=False, plot_if=True, plot_iv=False, xlim_if=None, ylim_if=None, xlim_iv=None, ylim_iv=None, label_xaxis=True, label_yaxis=True, show_volts_label=True, grid=True, font_size=12, if_iv_color='k', linewidth=1, bottom_left_spines_only=False, show_plot_already=True, save_voltage_traces_to=None, save_if_figure_to=None, save_iv_figure_to=None, save_if_data_to=None, save_iv_data_to=None, simulator='jNeuroML', num_processors=1, include_included=True, title_above_plot=False, return_axes=False, verbose=False) + +FILE + /usr/lib/python3.9/site-packages/pyneuroml/analysis/__init__.py + +``` +Most IDEs are able to show you this information as you use them in your Python scripts. + +(pyneuroml:gethelp)= +## Getting help + +For any questions regarding pyNeuroML, please open an issue on the GitHub issue tracker [here](https://github.com/NeuroML/pyNeuroML/issues). +Any bugs and feature requests can also be filed there. + +You can also use any of the {ref}`communication channels of the NeuroML community `. + +(pyneuroml:development)= +## Development + +pyNeuroML is developed on GitHub at [https://github.com/NeuroML/pyNeuroML](https://github.com/NeuroML/pyNeuroML) under the [LPGL-3.0 license](https://github.com/NeuroML/pyNeuroML/blob/master/LICENSE.lesser). +The repository contains the complete source code along with instructions on building/installing pyNeuroML. +Please follow the instructions there to build pyNeuroML from source. diff --git a/_sources/Userdocs/Specification.md b/_sources/Userdocs/Specification.md new file mode 100644 index 00000000..040714ea --- /dev/null +++ b/_sources/Userdocs/Specification.md @@ -0,0 +1,29 @@ +(userdocs:specification)= +# Schema/Specification + +```{admonition} NeuroML v2.3 is the current stable release of the language, and is described below. +For an overview of the various releases of the language see: {ref}`A brief history of NeuroML `. +``` + +We've briefly seen the XML representation of NeuroML models and simulations in the {ref}`Getting Started ` tutorials. +Here, we dive a little deeper into the underlying details of NeuroML. + +XML itself does not define a set of standard tags: any tags may be used as long as the resultant document is [well-formed](https://en.wikipedia.org/wiki/Well-formed_document). +Therefore, NeuroML defines a standard set of XML elements (the tags and attributes which specify the model and parameters, e.g. ``) that may be used in NeuroML documents: the NeuroML [XML Schema Definition](https://en.wikipedia.org/wiki/XML_Schema_(W3C)). +This is referred to as the NeuroML *schema* or the NeuroML *specification*. + +As the wiki page says: +```{epigraph} +XSD (XML Schema Definition), a recommendation of the World Wide Web Consortium (W3C), specifies how to formally describe the elements in an Extensible Markup Language (XML) document. It can be used by programmers to verify each piece of item content in a document, to assure it adheres to the description of the element it is placed in. +``` + +This gives us an idea of the advantages of using an XML based system. +All NeuroML models must use these pre-defined tags/components---this is what we check for when we {ref}`validate NeuroML models `. +A valid NeuroML model is said to adhere to the NeuroML schema. + +```{admonition} Purpose of the NeuroML specification/schema. +:class: note +The NeuroML schema/specification defines the structure of a valid NeuroML document. The {ref}`core NeuroML tools ` adhere to this specification and can read/write/interpret the language correctly. +``` + +In the next section, we learn more about the NeuroML 2 schema, and see how the dynamics of the NeuroML 2 entities are defined in LEMS. diff --git a/_sources/Userdocs/TestingNeuroMLModels.md b/_sources/Userdocs/TestingNeuroMLModels.md new file mode 100644 index 00000000..bcdfc1cc --- /dev/null +++ b/_sources/Userdocs/TestingNeuroMLModels.md @@ -0,0 +1,37 @@ +(userdocs:testing_validating_models)= +# Testing/validating NeuroML Models + +Models described in NeuroML can be run across multiple simulators, and it it essential that the activity (e.g. spike times) of the models are as close as possible across all of these independently developed platforms. + +It is also important to validate that the behaviour of a given NeuroML model reproduces some recorded aspect of the biological equivalent. + +(userdocs:testing_models)= +## Testing behaviour of NeuroML models across simulators + +This type of testing addresses the question: **Does a given NeuroML model produce the same results when run across multiple simulators?** + +(userdocs:testing_models:omv)= +### OMV - Open Source Brain Model Validation framework + +The OSB Model Validation framework was originally developed as an automated model validation package for [Open Source Brain](http://www.opensourcebrain.org) projects, which can be used for testing model behaviour across many [simulation engines](https://github.com/OpenSourceBrain/osb-model-validation/tree/master/omv/engines) both: + +- on your local machine when developing models +- on [GitHub Actions](https://github.com/features/actions), to ensure tests pass on every commit. + +This framework has been used to test the 30+ NeuroML and PyNN models described in the [Open Source Brain paper (Gleeson et al. 2019)](https://www.cell.com/neuron/fulltext/S0896-6273(19)30444-1), and [many more](https://github.com/OpenSourceBrain/.github/blob/main/testsheet/README.md). + +See https://github.com/OpenSourceBrain/osb-model-validation for more details. + +(userdocs:validating_models_bio)= +## Validating that NeuroML model reproduce biological activity + +This type of testing addresses the question: **How well does a given NeuroML model replicate the activity as seen in real neurons/channels/networks?** + +### SciUnit/NeuronUnit + +[SciUnit](https://scidash.org/sciunit.html) is a Python framework for test-driven validation of scientific models, and [NeuronUnit](https://scidash.org/neuronunit.html) + is a package based on this for data-driven validation of neuron and ion channel models. See also [SciDash](https://scidash.org/) for more information. + +Interactive Jupyter notebooks for running NeuronUnit examples can be found [this repository](https://github.com/scidash/neuronunit/tree/master/docs). + +TODO: Add details on using [SciUnit](https://scidash.org/sciunit.html) and [NeuronUnit](https://scidash.org/neuronunit.html) with NeuroML models. diff --git a/_sources/Userdocs/UnitsAndDimensions.md b/_sources/Userdocs/UnitsAndDimensions.md new file mode 100644 index 00000000..d4ab3813 --- /dev/null +++ b/_sources/Userdocs/UnitsAndDimensions.md @@ -0,0 +1,19 @@ +(userdocs:unitsanddimensions)= +# Units and dimensions + +Support for dimensional quantities is a fundamental (and essential) feature of NeuroML, backed up by support for units and dimensions in LEMS. + +The basic rules are: + +- specify the **dimensions** of quantities in LEMS +- use compatible **units** defined in the NeuroML schema in NeuroML models. + +The main motivation for this is that fundamental expressions for defining a model are independent of any particular units. +For example, Ohm's law, **V = I * R** relates to quantities with dimensions voltage, current and resistance, not millivolts, picoamps, ohms, etc. + +Users can therefore use a wide range of commonly used units for each dimension defined in the {ref}`standard unit and dimension definitions ` of NeuroML 2 without worrying about conversion factors. + +Additionally, please keep in mind that: + +- all quantities are saved and {ref}`recorded ` in SI Units +- when plotting data using NeuroML/LEMS using the {ref}`Line ` component, users can use the `scale` parameter to convert quantities to other units. diff --git a/_sources/Userdocs/Usage.md b/_sources/Userdocs/Usage.md new file mode 100644 index 00000000..e410b1e3 --- /dev/null +++ b/_sources/Userdocs/Usage.md @@ -0,0 +1,140 @@ +(userdocs:usage)= +# How to use this documentation + +This documentation is generated using [Jupyter books](https://jupyterbook.org/intro.html). +You can learn more about the project on their website. + +(userdocs:usage:structure)= +## Structure and navigation + +```{admonition} Close the left hand side bar using the burger menu on the left side of the top panel. +:class: tip +You can close the left hand side bar by clicking the burger menu on the left side of the top panel. +This increases the width of the middle section of the documentation and can be helpful on smaller screens. +Clicking the hamburger menu again will re-open it. +``` + +The documentation is divided into a few parts that can be seen in the *left hand side navigation bar*: + +- **User documentation**: this includes documentation for anyone looking to use NeuroML +- **NeuroML events**: any events related to NeuroML will be listed here +- **The NeuroML Initiative**: this includes documentation on the NeuroML community +- **Developer documentation**: this includes information for individuals looking to contribute to NeuroML (either the standard or the software) +- **Reference**: this includes the glossary of terms and the bibliography. + +Each part contains different chapters, which can each contain different sections. +Each page in the documentation also has its own navigation in the *right hand side bar*. + +(userdocs:usage:jupyterbooks)= +## Using Jupyter notebooks included in the documentation +```{admonition} Familiar with Jupyter Notebooks? Skip ahead to the next section. +:class: tip +If you are familiar with Jupyter Notebooks, you can skip ahead to the {ref}`Getting started with NeuroML ` section. +``` + + +The most important feature of Jupyter books is that it allows you to include [Jupyter notebooks](https://jupyter-notebook.readthedocs.io/en/stable/notebook.html) in the documentation. +This allows us to write documentation which includes code examples that can be modified and executed by users interactively in their browsers *without having to install anything on their local machines*. +For example, these are used in the {ref}`Getting Started ` section. + +Each Jupyter notebook in the documentation includes a rocket icon 🚀 in the top bar: + +```{figure} ../images/izhikevich-rocket.png +:alt: Click the rocket icon in top panel of executable pages to execute them in Binder or Google Collaboratory. +:align: center + +Click the rocket icon in top panel of executable pages to execute them in Binder or Google Collaboratory. +``` +Clicking this icon will allow you to run the Jupyter Notebook: + +```{figure} ../images/izhikevich-rocket-options.png +:alt: You can run the Jupyter Notebook on Binder or Google Colaboratory. +:align: center + +You can run the Jupyter Notebook on Binder or Google Colaboratory. +``` + +You can choose from freely available services such as [Binder](https://mybinder.org/) and [Google Colaboratory](https://colab.research.google.com/). +Both Binder and Google Colaboratory will take you to these services and load the Jupyter Notebook for you to use. +The Live code option uses Binder but allows you to run the code in the current tab itself. +However, please note that this option does not include the full Jupyter Notebook features that Binder and Google Colaboratory provide. + +```{admonition} Run Binder and Google Colaboratory in a new tab. +:class: tip +It is suggested to right click and select "Open in new tab" so that the tab with the NeuroML documentation remains open. +In most browsers, you can also use `Ctrl + click` to open links in a new tab: +``` + +```{figure} ../images/izhikevich-binder.png +:alt: Izhikevich example running in Binder. +:align: center +:scale: 30 % + +Izhikevich example running in Binder +``` +```{figure} ../images/izhikevich-google.png +:alt: Izhikevich example running in Google Colaboratory. +:align: center +:scale: 30 % + +Izhikevich example running in Google Colaboratory. +``` + +```{figure} ../images/izhikevich-livecode.png +:alt: Izhikevich example running on Binder but using the Live Code option. +:align: center +:scale: 30 % + +Izhikevich example running in Binder but using the Live Code option. +``` + +When running the Jupyter notebooks using these services, you can make changes to the code and re-run it as required. +On Binder and Google Colaboratory, which provide the full range of Jupyter Notebook features, you can also run all the code cells at once in sequence. +Please see the documentation pages to learn more about using Binder and Google Colaboratory [here](https://mybinder.readthedocs.io/en/latest/) and [here](https://colab.research.google.com/notebooks/basic_features_overview.ipynb) respectively. +General information on using Jupyter Notebooks and the interface can be found in the documentation [here](https://jupyter-notebook.readthedocs.io/en/stable/notebook.html#starting-the-notebook-server). + +(userdocs:usage:jupyterbooks:locally)= +### Downloading Jupyter Notebooks to run locally on your machine + +Jupyter Notebooks can also be downloaded and run locally on your machine. +To download the notebooks, use the Download link in the top panel: + +```{figure} ../images/jupyter-download.png +:alt: Jupyter notebooks can be downloaded using the Download link in the top panel. +:align: center + +Jupyter notebooks can be downloaded using the Download link in the top panel. +``` + +You will need to install the Python Jupyter Notebook packages to do so. +Please refer to the Jupyter Notebook [documentation](https://jupyter.readthedocs.io/en/latest/install/notebook-classic.html#alternative-for-experienced-python-users-installing-jupyter-with-pip) to see how you can install Jupyter Notebooks. +Additionally, you will also need to install the {ref}`NeuroML software ` to run these notebooks. +Information on using Jupyter Notebooks and the interface can be found in the documentation [here](https://jupyter-notebook.readthedocs.io/en/stable/notebook.html#starting-the-notebook-server). + + +(userdocs:usage:pdf)= +## Downloading this documentation as PDF + +You can download this documentation as PDF pages for offline use. + +To download individual pages, use the download icon in the top bar. +This will generate a PDF page of the current page for you, using your browser's "print to file" functionality. + +% relative links to external files don't yet work. See https://github.com/executablebooks/jupyter-book/issues/1657 +You can also download the complete book as a PDF [here](https://docs.neuroml.org/_static/files/neuroml-documentation.pdf). + +(userdocs:usage:bugs)= +## Reporting bugs and issues + +Please report any issues that you may find in the documentation so that it can be improved. +To report an issue on a particular page, you can use the "open issue" link under the GitHub icon in the top panel. +Additionally, you can also suggest edits by editing the page in a fork and opening a pull request using the "suggest and edit" link. + +```{figure} ../images/jupyterbook-issue.png +:alt: You can report issues and suggest edits to the documentation to help us improve it using the options in the GitHub icon in the top panel. +:align: center + +You can report issues and suggest edits to the documentation to help us improve it using the options in the GitHub icon in the top panel. +``` + +You can also always contact the NeuroML community using our {ref}`communication channels ` if required. diff --git a/_sources/Userdocs/ValidatingNeuroMLModels.md b/_sources/Userdocs/ValidatingNeuroMLModels.md new file mode 100644 index 00000000..1475858e --- /dev/null +++ b/_sources/Userdocs/ValidatingNeuroMLModels.md @@ -0,0 +1,137 @@ +(userdocs:validating_models)= +# Validating NeuroML Models +```{admonition} Validate NeuroML 2 files before using them. +:class: tip +It is good practice to validate NeuroML 2 files to check them for correctness before using them. +``` + +Models described in NeuroML must adhere to the NeuroML {ref}`specification `. +This allows all NeuroML models to be checked for correctness: **validation**. +There are a number of ways of **validating** NeuroML model files. + +(userdocs:validating_models:cli)= +## Using the command line tools + +Both `pynml` (provided by {ref}`pyNeuroML `) and `jnml` (provided by {ref}`jNeuroML `) can validate individual NeuroML files: + +```{code-block} console +Usage: + +# For NeuroML 2 +jnml -validate +pynml -validate + +# For NeuroML 1 (deprecated) +jnml -validatev1 +pynml -validatev1 +``` + +(userdocs:validating_models:python)= +## Using the Python API + +The {ref}`pyNeuroML ` Python API provides a number of methods to validate NeuroML 2 files. +The first is the aptly named `validate_neuroml2` function: + +```{code-block} python + +from pyneuroml.pynml import validate_neuroml2 + +... + +validate_neuroml2(nml_filename) +``` +Similarly, the `validate_neuroml1` function can be used to validate NeuroML v1 files. + +If you are loading NeuroML files into your Python script, the `read_neuroml2_file` function also includes validation: + +```{code-block} python + +from pyneuroml.pynml import read_neuroml2_file + + +.... + + +read_neuroml2_file(nml_filename, include_includes=True, check_validity_pre_include=True) +``` + +This will read (load) the provided NeuroML 2 file and all the files that are recursively included by it, and validate them all while it loads them. + +(userdocs:validating_models:tests)= +## List of validation tests + + +These tests are made against the Schema document. +```{list-table} +:header-rows: 1 +:name: validation-tests-schema + +* - Test + - Description +* - Check names + - Check that names of all elements, attributes, parameters match those provided in the schema +* - Check types + - Check that the types of all included elements +* - Check values + - Check that values follow given restrictions +* - Check inclusion + - Check that required elements are included +* - Check cardinality + - Check the number of elements +* - Check hierarchy + - Check that child/children elements are included in the correct parent elements +* - Check sequence order + - Check that child/children elements are included in the correct order + +``` + +These are additional validation tests that are run on models (defined [here](https://github.com/NeuroML/org.neuroml.model/blob/development/src/main/java/org/neuroml/model/util/NeuroML2Validator.java#L57)): +```{list-table} +:header-rows: 1 +:name: validation-tests-additional + +* - Test + - Description +* - Check top level ids + - Check that top level (root) elements have unique ids +* - Check {ref}`Network ` level ids + - Check that child/children of the {ref}`Network ` element have unique ids +* - Check {ref}`Cell ` {ref}`Segment ` ids + - Check that all {ref}`Segment `s in a {ref}`Cell ` have unique ids +* - Check single {ref}`Segment ` without parent + - Check that only one {ref}`Segment ` is without parents (the soma {ref}`Segment `) +* - Check {ref}`SegmentGroup ` ids + - Check that all {ref}`SegmentGroup `s in a {ref}`Cell ` have unique ids +* - Check {ref}`Member ` segment ids exist + - Check that {ref}`Segment `s referred to in {ref}`SegmentGroup ` {ref}`Member `s exist +* - Check {ref}`SegmentGroup ` definition + - Check that {ref}`SegmentGroup `s being referenced are defined +* - Check {ref}`SegmentGroup ` definition order + - Check that {ref}`SegmentGroup `s are defined before being referenced +* - Check included {ref}`SegmentGroup `s + - Check that {ref}`SegmentGroup `s referenced by {ref}`Include ` elements of other {ref}`SegmentGroup `s exist +* - Check `numberInternalDivisions` + - Check that {ref}`SegmentGroup `s define `numberInternalDivisions` (used by simulators to discretize un-branched branches into compartments for simulation) +* - Check included model files + - Check that model files included by other files exist +* - Check {ref}`Population ` component + - Check that a component id provided to a {ref}`Population ` exists +* - Check ion channel exists + - Check that an ion channel used to define a {ref}`ChannelDensity ` element exists +* - Check concentration model species + - Check that the species used in {ref}`ConcentrationModel ` elements are defined +* - Check {ref}`Population ` size + - Check that the `size` attribute of a {ref}`PopulationList ` matches the number of defined {ref}`Instance `s +* - Check {ref}`Projection ` component + - Check that {ref}`Population `s used in the {ref}`Projection ` elements exist +* - Check {ref}`Connection ` {ref}`Segment ` + - Check that the {ref}`Segment ` used in {ref}`Connection ` elements exist +* - Check {ref}`Connection ` pre/post cells + - Check that the pre- and post-synaptic cells used in {ref}`Connection ` elements exist and are correctly specified +* - Check {ref}`Synapse ` + - Check that the {ref}`Synapse ` component used in a {ref}`Projection ` element exists +* - Check root id + - Check that the root {ref}`Segment ` in a {ref}`Cell ` morphology has id \(0\) + + +``` diff --git a/_sources/Userdocs/VisualisingCells.md b/_sources/Userdocs/VisualisingCells.md new file mode 100644 index 00000000..84116dfc --- /dev/null +++ b/_sources/Userdocs/VisualisingCells.md @@ -0,0 +1,90 @@ +(userdocs:visualising_cells)= +# Visualising and analysing cell models + +The NeuroML ecosystem include a number of utilities for analysis and visualisation of cells. +Cell morphologies can either be visualised programmatically using the core tools, or using the many advanced neuroinformatics tools in the ecosystem that support NeuroML. +In addition to the resources listed below, you can also use the visualisation features of any other tools that read NeuroML. +E.g., {ref}`NetPyNE and NetPyNE-UI `, {ref}`neuroConstruct `, {ref}`Arbor ` and others. + + +(userdocs:visualising_cells:morph)= +## Visualising morphology of multi-compartmental cell models + +Multi-compartmental cells can be visualised using the [plot_2D](https://pyneuroml.readthedocs.io/en/development/pyneuroml.plot.html#pyneuroml.plot.PlotMorphology.plot_2D) and [plot_interactive_3D](https://pyneuroml.readthedocs.io/en/development/pyneuroml.plot.html#pyneuroml.plot.PlotMorphology.plot_interactive_3D) methods included in {ref}`pyNeuroML `. +This functionality is also exposed via the `pynml-plotmorph` command line tool. + +```{figure} ../images//test_morphology_plot_2d_Cell_497232312_cell_nml_xy.png +:alt: Morphology of example cell plotted with `plot_2D` +:align: center +:width: 50% + +Morphology of example cell plotted with `plot_2D` in the X-Y plane. +``` + +
+
+ Morphology of example cell visualised interactively using `plot_interactive_3D` +
+ + +(userdocs:visualising_cells:morph:nmldb)= +### Visualising morphology of multi-compartmental cell models in NeuroML-db +The {ref}`NeuroML-DB ` platform shows detailed cell morphologies of all cells included in its database. + +```{figure} ../images/nml-db-morphology.png +:alt: Morphology of cell shown in NeuroML-DB. +:align: center +:width: 70% + +Visualisation of morphology of an example cell on NeuroML-DB. +``` +(userdocs:visualising_cells:morph:osb)= +### Visualising morphology of multi-compartmental cell models in Open Source Brain +The {ref}`Open Source Brain ` platform also provides advanced visualisation capabilities that can be used to visualise the morphologies of NeuroML cells. + +```{figure} ../images/osb-morphology.png +:alt: Morphology of cell shown on Open Source Brain. +:align: center +:width: 70% + +Interactive visualisation of morphology of an example cell on Open Source Brain. +``` + + +(userdocs:visualising_cells:ephys)= +## Analysing cell electrophysiology + +The core tools also include utilities to aid in the analysis of cell electrophysiology. +{ref}`pyNeuroML ` includes the [generate_current_vs_frequency_curve](https://pyneuroml.readthedocs.io/en/development/pyneuroml.analysis.html#pyneuroml.analysis.generate_current_vs_frequency_curve) utility function that can be used to generate current-frequency, current-sub-threshold voltage, and to plot voltage traces generated at the soma for different current injections. +For example, we can analyse the {ref}`OLM cell from our tutorial `: +``` +generate_current_vs_frequency_curve("source/Userdocs/NML2_examples/olm.cell.nml", "olm", simulator="jNeuroML_NEURON", plot_iv=True, plot_if=True, plot_voltage_traces=True) +``` + +This will generate these figures: + +```{figure} ../images/olm-cell-fi.png +:alt: F-I curve for OLM cell generated using `generate_current_vs_frequency_curve`. +:align: center +:width: 70% + +F-I curve for OLM cell generated using `generate_current_vs_frequency_curve`. +``` + +```{figure} ../images/olm-cell-subthresholdVi.png +:alt: Current vs sub-threshold voltage curve for OLM cell generated using `generate_current_vs_frequency_curve`. +:align: center +:width: 70% + +Current vs sub-threshold voltage curve for OLM cell generated using `generate_current_vs_frequency_curve`. +``` + +```{figure} ../images/olm-cell-voltage-traces.png +:alt: Voltage traces for OLM cell with different injection currents generated using `generate_current_vs_frequency_curve`. +:align: center +:width: 70% + +Voltage traces for OLM cell with different injection currents generated using `generate_current_vs_frequency_curve`. +``` diff --git a/_sources/Userdocs/VisualisingChannels.md b/_sources/Userdocs/VisualisingChannels.md new file mode 100644 index 00000000..1916d20c --- /dev/null +++ b/_sources/Userdocs/VisualisingChannels.md @@ -0,0 +1,125 @@ +(userdocs:visualising_channels)= +# Visualising and analysing ion channel models + +A core part of NeuroML is the ability to specify voltage dependent (and potentially concentration dependent) membrane conductances, which are due to ion channels. + + +## Help converting/examining channels in NeuroML + +Converting your own ion channel models to NeuroML is facilitated by examples (e.g. [a simple HH Na+ channel](https://github.com/NeuroML/NeuroML2/tree/master/examples/NML2_SimpleIonChannel.nml)) and the specification documentation (e.g. for {ref}` `, {ref}` `, {ref}` `, but there are also a number of software tools which can be used to view the internal properties of the ion channels, as well as their behaviour. + +```{admonition} Converting cell models to NeuroML +:class: tip +Note: there is a full guide to {ref}`Converting cell models to NeuroML and sharing them on Open Source Brain ` which uses some of the tools and methods below. +``` + + +### 1) Use jnml -info (note not in pynml yet...) + +{ref}`jNeuroML ` can be used on channel files for a quick summary of the contents. + +``` +> jnml NaConductance.channel.nml -info + + jNeuroML v0.12.0 + +Information on contents of NeuroML 2 file +Ion Channel NaConductance: + ID: NaConductance + Description: HH Na Channel + Gates: + gate m: + instances: 3 + forward rate: 1e3 * (v - (-0.04))/0.01 / ( 1 - exp(-(v - (-0.04)) / 0.01)) + reverse rate: 4e3 * exp((v - (-0.065))/-0.018) + gate h: + instances: 1 + forward rate: 70 * exp((v - (-0.065))/-0.02) + reverse rate: 1e3 /(1 + exp((v - (-0.035))/0.01)) +``` + +(userdoc:pynml-channelanalysis)= +### 2) Use pynml utilities in pyNeuroML + +{ref}`pyNeuroML ` comes with 3 utilities which help enable examination of the properties of ion channels, both based on NeuroML and NEURON mod files. + +``` +pynml-channelanalysis NaConductance.channel.nml # Analyse a NeuroML 2 channel +pynml-plotchan cell.nml # Plot distribution of peak channel conductances over cell morphology +pynml-modchananalysis NaConductance # Analyse a NEURON channel e.g. from NaConductance.mod + +``` +![pynml_channelanalyse](../images/pynml-channelanalysis.png) + +`pynml-channelanalysis` includes a number of options for generating graphs of channel activity under different conditions (see [here](https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/tree/master/NMC/NeuroML2#analyse-channel-properties) for details). + +``` +pynml-channelanalysis NaTa_t.channel.nml -erev 55 -stepTargetVoltage 10 -clampDuration 5 -i -duration 7 -clampDelay 1 +``` +![pynml_analyse_Na](../images/NaTa.png) + + +`pynml-plotchan` will plot the distribution of peak conductances of all channels in a cell over its morphology, and also show distribution as a function of distance from the soma. +For example, the figure below shows the distribution of the Ih channel in the layer 5 pyramidal neuron model on the neuronal morphology on the left, and the value at different distances from the soma on the right. + +![pynml_analyse_plotchan](../images/Ih-combined.png) + +This functionality is also available as a [Python function](https://pyneuroml.readthedocs.io/en/stable/pyneuroml.analysis.html#pyneuroml.analysis.ChannelDensityPlot.plot_channel_densities) for use in scripts. + +### 4) Load cell model on to OSBv1 & analyse the channels + +Open Source Brain (version 1) includes channel analysis functionalities. + +![osb_channel_analysis](../images/osb-channel-analysis.png) + +### 5) Export to one of the supported simulators + +Exporting to Neuron say (`jnml LEMS_NML2_Ex5_DetCell.xml -neuron`) will produce mod files with the "flattened" equations: +``` +... +DERIVATIVE states { + rates() + m_q' = rate_m_q + h_q' = rate_h_q + +} + +PROCEDURE rates() { + + m_forwardRate_x = (v - m_forwardRate_midpoint ) / m_forwardRate_scale ? evaluable + if (m_forwardRate_x != 0) { + m_forwardRate_r = m_forwardRate_rate * m_forwardRate_x / (1 - exp(0 - m_forwardRate_x )) ? evaluable cdv + } else if (m_forwardRate_x == 0) { + m_forwardRate_r = m_forwardRate_rate ? evaluable cdv + } +... +``` +Exporting to Brian 2 (`jnml LEMS_NML2_Ex5_DetCell.xml -brian2`) will also produce a large file with the explicit expressions... +``` +... +hhcell_eqs=Equations(''' + dbioPhys1_membraneProperties_NaConductances_NaConductance_m_q/dt = ((bioPhys1_membraneProperties_NaConductances_NaConductance_m_inf - bioPhys1_membraneProperties_NaConductances_NaConductance_m_q) / bioPhys1_membraneProperties_NaConductances_NaConductance_m_tau) : 1 + dbioPhys1_membraneProperties_NaConductances_NaConductance_h_q/dt = ((bioPhys1_membraneProperties_NaConductances_NaConductance_h_inf - bioPhys1_membraneProperties_NaConductances_NaConductance_h_q) / bioPhys1_membraneProperties_NaConductances_NaConductance_h_tau) : 1 + dbioPhys1_membraneProperties_KConductances_KConductance_n_q/dt = ((bioPhys1_membraneProperties_KConductances_KConductance_n_inf - bioPhys1_membraneProperties_KConductances_KConductance_n_q) / bioPhys1_membraneProperties_KConductances_KConductance_n_tau) : 1 + dv/dt = ((iChannels + iSyn) / totCap) : volt + morph1_0_LEN = 1.0 * meter : meter +... + bioPhys1_membraneProperties_KConductances_erev = -0.077 * volt : volt + bioPhys1_membraneProperties_KConductances_condDensity = 360.0 * kilogram**-1 * meter**-4 * second**3 * amp**2 : kilogram**-1 * meter**-4 * second**3 * amp**2 + bioPhys1_membraneProperties_KConductances_KConductance_conductance = 1.0E-11 * siemens : siemens + bioPhys1_membraneProperties_KConductances_KConductance_n_instances = 4.0: 1 + bioPhys1_membraneProperties_KConductances_KConductance_n_forwardRate_rate = 100.0 * second**-1 : second**-1 + bioPhys1_membraneProperties_KConductances_KConductance_n_forwardRate_midpoint = -0.055 * volt : volt + bioPhys1_membraneProperties_KConductances_KConductance_n_forwardRate_scale = 0.01 * volt : volt + bioPhys1_membraneProperties_KConductances_KConductance_n_reverseRate_rate = 125.0 * second**-1 : second**-1 + bioPhys1_membraneProperties_KConductances_KConductance_n_reverseRate_midpoint = -0.065 * volt : volt + bioPhys1_membraneProperties_KConductances_KConductance_n_reverseRate_scale = -0.08 * volt : volt +``` + +Both very verbose, but it's possible to see at least what explicit expressions are being used for the channels... + +### 6) Use NeuroML-DB + +[NeuroML-DB](https://neuroml-db.org) also provides analysis features for Ion channels. + +![neuromldb-channel-analysis](../images/neuromldb-channel-analysis.png) diff --git a/_sources/Userdocs/VisualisingNeuroMLModels.md b/_sources/Userdocs/VisualisingNeuroMLModels.md new file mode 100644 index 00000000..78a5550f --- /dev/null +++ b/_sources/Userdocs/VisualisingNeuroMLModels.md @@ -0,0 +1,360 @@ +(userdocs:visualising_models)= +# Visualising NeuroML Models + +A number of the {ref}`NeuroML software tools ` can be used to easily visualise models described in NeuroML. + +(userdoc:visualising_models:summary)= +## Get a quick summary of your model + +(userdoc:visualising_models:summary:cli)= +### Using command line tools + +You can get a quick summary of your NeuroML model using the `pynml-summary` command line tool that is provided by {ref}`pyNeuroML `: + +```{code-block} console +Usage: +pynml-summary +``` + +For example, to get a quick summary of the [Primary Auditory Cortex model by Dave Beeman](https://github.com/OpenSourceBrain/ACnet2/blob/master/neuroConstruct/generatedNeuroML2/MediumNet.net.nml) (see it [here on Open Source Brain](https://www.opensourcebrain.org/projects/acnet2)), one can run: +```{code-block} console +pynml-summary MediumNet.net.nml + +******************************************************* +* NeuroMLDocument: network_ACnet2 +* +* PulseGenerator: ['BackgroundRandomIClamps'] +* +* Network: network_ACnet2 (temperature: 6.3 degC) +* +* 60 cells in 2 populations +* Population: baskets_12 with 12 components of type bask +* Locations: [(372.5585, 75.3425, 459.2106), ...] +* Properties: color=0.0 0.19921875 0.59765625; +* Population: pyramidals_48 with 48 components of type pyr_4_sym +* Locations: [(64.2564, 0.6838, 94.8305), ...] +* Properties: color=0.796875 0.0 0.0; +* +* 984 connections in 4 projections +* Projection: SmallNet_bask_bask from baskets_12 to baskets_12, synapse: GABA_syn_inh +* 60 connections: [(Connection 0: 3:0(0.41661) -> 0:0(0.68577)), ...] +* Projection: SmallNet_bask_pyr from baskets_12 to pyramidals_48, synapse: GABA_syn +* 336 connections: [(Connection 0: 10:0(0.05824) -> 0:6(0.02628)), ...] +* Projection: SmallNet_pyr_bask from pyramidals_48 to baskets_12, synapse: AMPA_syn_inh +* 252 connections: [(Connection 0: 1:0(0.89734) -> 0:1(0.09495)), ...] +* Projection: SmallNet_pyr_pyr from pyramidals_48 to pyramidals_48, synapse: AMPA_syn +* 336 connections: [(Connection 0: 14:0(0.52814) -> 0:3(0.10797)), ...] +* +* 14 inputs in 1 input lists +* Input list: BackgroundRandomIClamps to pyramidals_48, component BackgroundRandomIClamps +* 14 inputs: [(Input 0: 37:0(0.500000)), ...] +* +******************************************************* +``` +(userdoc:visualising_models:summary:pyNeuroML)= +### Using pyNeuroML + +You can also get a summary of your model from within your {ref}`pyNeuroML ` script itself using the `summary` function: + +```{code-block} python +import pyneuroml.pynml + +... + + +pyneuroml.pynml.summary(nml2_doc) +``` + +(userdoc:visualising_models:png)= +## View the 3D structure of your model + +(userdoc:visualising_models:png:cli)= +### Using command line tools + +You can generate an image of the 3D structure of the NeuroML model using the `pynml` command provided by {ref}`pyNeuroML `, or using the `jnml` command provided by {ref}`jNeuroML `: + +```{code-block} console +Usage: +pynml -png/-svg +jnml -png/-svg +``` + +For example, to generate a PNG image of the Auditory Cortex model used above, we can use (use `-svg` to generate a vectorised SVG image instead of a PNG): + +```{code-block} console +pynml -png MediumNet.net.nml +``` + +This generates the following image showing different views of the network : + +```{figure} ../images/Acnet-medium.net.png +:alt: Graphical view of the Auditory Cortex model generated with pynml +:align: center +:scale: 20 % + +Graphical view of the Auditory Cortex model generated with pynml +``` + +An visualiser is also included in pyneuroml as `pynml-plotmorph` which includes both 2D and 3D views: + +```{code-block} console +Usage: +pynml-plotmorph +pynml-plotmorph -i +``` + +```{figure} ../images/20231122-ACNet.png +:alt: A network visualised with `pynml-plotmorph` +:align: center +:width: 30% + +Matplotlib based 2D visualisation of a network with `pynml-plotmorph`. +``` +
+
+ Example network visualised interactively using `pynml-plotmorph`

+
+ + +You can also generate graphical representations that can be viewed with the [Persistence of Vision Raytracer (POV-Ray)](http://povray.org/) tool using the `pynml-povray` tool. +For example: + +```{code-block} console +pynml-povray MediumNet.net.nml -scalez 8 +povray Antialias=On Antialias_Depth=10 Antialias_Threshold=0.1 Output_to_File=y Output_File_Type=N Output_File_Name=Acnet-medium.povray +W1200 +H900 MediumNet.net.nml.pov + +``` +generates this image: + +```{figure} ../images/Acnet-medium.povray.png +:alt: Graphical view of the Auditory Cortex model generated with pynml-povray and POV-Ray +:align: center +:scale: 50 % + +Graphical view of the Auditory Cortex model generated with pynml-povray and POV-Ray +``` + + +You can also use POV-Ray interactively. +Please refer to the [official website](http://povray.org/download/) for more information on installing and using POV-Ray. +On Fedora Linux systems, you can install it from the Fedora repositories using `dnf`: + +```{code-block} console +sudo dnf install povray +``` + +(userdoc:visualising_models:png:pyNeuroML)= +### Using pyNeuroML + +These functions are also exposed as Python functions in {ref}`pyNeuroML `, so that you can use them directly in Python scripts: + +```{code-block} python +import pyneuroml.pynml + +pyneuroml.pynml.nml2_to_png(nml2_doc) +pyneuroml.pynml.nml2_to_svg(nml2_doc) + + +from pyneuroml.plot.PlotMorphology import plot_2D +from pyneuroml.plot.PlotMorphologyVispy import plot_interactive_3D + +plot_2D(nml2_doc) +plot_interactive_3D(nml2_doc) +``` + +```{admonition} Open Source Brain uses NeuroML. +:class: tip +The [Open Source Brain platform](https://www.opensourcebrain.org) generates the interactive visualisations from NeuroML sources. +See the Auditory Cortex model on Open Source Brain [here](https://www.opensourcebrain.org/projects/acnet2). +``` + + +(userdoc:visualising_models:graph)= +## View the connectivity graph of your model + +(userdoc:visualising_models:graph:cli)= +### Using command line tools +```{admonition} Use levels to generate connectivity graphs with different levels of detail. +:class: tip dropdown + +Positive values for levels will generate figures at the population level, while negative values will generate them at the level of cells. +``` + +You can generate an image of the 3D structure of the NeuroML model using `pynml`: + +```{code-block} console +Usage: +pynml -graph +``` + +For example, to generate a PNG image of the Auditory Cortex model used above, we can use: + +```{code-block} console +pynml MediumNet.net.nml -graph 1d +``` + +This generates the following image showing different views of the network : + +```{figure} ../images/Acnet-medium-graph-level1.png +:alt: Level 1 network graph generated by pynml +:align: center + +Level 1 network graph generated by pynml +``` + +You can modify the level of detail included in the graph by using different values of levels. +For example, this command generates a level 5 graph: + +```{code-block} console +pynml MediumNet.net.nml -graph 5d +``` + +```{figure} ../images/Acnet-medium-graph-level5.png +:alt: Level 5 network graph generated by pynml +:align: center +:scale: 60 % + +Level 5 network graph generated by pynml +``` +(userdoc:visualising_models:graph:pyNeuroML)= +### Using pyNeuroML + +You can also generated these figures from within your {ref}`pyNeuroML ` script itself using the `generate_nmlgraph` function: + +```{code-block} python +import pyneuroml.pynml + +... + + +pyneuroml.pynml.generate_nmlgraph(nml2_doc, level="1", engine="dot") +``` + + +(userdoc:visualising_models:matrix)= +## View the connectivity matrices of the model + +You can generate the connectivity matrices of projections between neuronal populations of the NeuroML model using `pynml`: + +```{code-block} console +Usage: +pynml -matrix +``` + +For example, to generate a PNG image of the connectivity matrices in the Auditory Cortex model used above, we can use: + +```{code-block} console +pynml MediumNet.net.nml -matrix 1 +``` + +This generates the following images showing different views of the connectivity matrices in the network : + +
+
+
+
+ +```{image} ../images/Acnet-matrix-1.png +:alt: Connectivity matrix generated by pynml - sum of signed weights +:scale: 50 % +``` + +
+ +
+
+
+ +```{image} ../images/Acnet-matrix-2.png +:alt: Connectivity matrix generated by pynml - average magnitude of conductance received by post-synaptic neurons +:scale: 50 % +``` +
+ +
+
+
+ +```{image} ../images/Acnet-matrix-3.png +:alt: Connectivity matrix generated by pynml - number of connections +:scale: 50 % +``` +
+ +
+
+
+ +```{image} ../images/Acnet-matrix-4.png +:alt: Connectivity matrix generated by pynml - average conductance received by post-synaptic neurons +:scale: 50 % +``` +
+ +
+
+
+ +```{image} ../images/Acnet-matrix-5.png +:alt: Connectivity matrix generated by pynml - average weight per connection +:scale: 50 % +``` + +
+ +
+
+
+ + +(userdoc:visualising_models:lemsgraph)= +## View graph of the simulation instance of the model + +(userdoc:visualising_models:lemsgraph:cli)= +### Using command line tools + +When you have created a simulation instance of the NeuroML model using LEMS, you can also visualise this using `pynml` or `jnml`: + +```{code-block} console +Usage: +pynml -lems-graph +jnml -lems-graph +``` + +For example, to generate the LEMS graph for the {ref}`Izhikevich neuron network example `, we will use: + +```{code-block} console +jnml LEMS_example_izhikevich2007network_sim.xml -lems-graph +``` +will generate: +```{figure} ../Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.png +:alt: Model summary graph generated using jnml. +:align: center +:scale: 50% + +A summary graph of the model generated using jnml. +``` + +Note that the `-lems-graph` option does not take options for levels of detail. +It shows all the details of the simulation instance, and so is better suited for simpler models rather than detailed conductance based network models. +For example, for the Auditory Cortex model, {download}`this <../images/Acnet-LEMS.png>` very very detailed image is generated (please click to open: it is too large to display in the page). + + +(userdoc:visualising_models:lemsgraph:pyneuroml)= +### Using pyNeuroML + +You can also generated these figures from within your {ref}`pyNeuroML ` script itself using the `generate_lemsgraph` function: + +```{code-block} python +import pyneuroml.pynml + +... + +pyneuroml.pynml.generate_lemsgraph(lems_file) +``` + +## Viewing/analysing ion channel dynamics + +There is a dedicated section on {ref}`visualising and analysing ion channel models `. diff --git a/_sources/Userdocs/Walkthroughs/RayEtAl2020/Conversion.md b/_sources/Userdocs/Walkthroughs/RayEtAl2020/Conversion.md new file mode 100644 index 00000000..aac2007f --- /dev/null +++ b/_sources/Userdocs/Walkthroughs/RayEtAl2020/Conversion.md @@ -0,0 +1,762 @@ +# Converting to NeuroML + +On inspection of the model, we see that it has two biophysically detailed cell models: + +- the GGN (Giant GABAergic Neuron) +- the KC (Kenyon cell) + +## Converting the Giant GABAergic Neuron +### Step 1) Exporting morphology of the GGN + +Let's start with the GGN first. +It's morphology is defined as an SWC file in [this file](https://github.com/OpenSourceBrain/262670/blob/master/NEURON/mb/cell_templates/GGN_20170309_sc.swc). +One can download this file and view the morphology in a tool, like the [HBP morphology viewer](https://neuroinformatics.nl/HBP/morphology-viewer/#). + +```{figure} ../../../images/GGN.png +:alt: Screen shot showing visualisation of the GGN in the HBP morphology viewer +:align: center +:scale: 20 % + +Visualisation of the GGN in the HBP morphology viewer. +``` + +A [NEURON HOC script](https://github.com/OpenSourceBrain/262670/blob/master/NEURON/mb/cell_templates/GGN_20170309_sc.hoc) that includes the full morphology and the biophysics is also included. + +Let us export the morphology first. +pyNeuroML includes the `export_to_neuroml2` helper function that exports a cell model in NEURON to NeuroML. +We can write a short script to use this function to export the morphology from the provided HOC script. + +```{literalinclude} ./scripts/cellmorph2nml.py +---- +language: python +---- +``` + +What we're doing here is using the HOC script to build the cell model in NEURON, and then exporting it to NeuroML. +Calling it as `python cellmorph2nml.py GGN` will create a new file: `GGN.morph.cell.nml` which contains the morphology of the cell in NeuroML format. +Note that while `export_to_neuroml2` does allow exporting the biophysics of the cell, it is better to add these manually later once one has gone through and converted the required ion channels and so on. + +We can visualise the morphology using the pyNeuroML tools: + +```{code-block} bash +pynml-plotmorph -i GGN.morph.cell.nml +``` + + +```{figure} ../../../images/GGN-vispy .png +:alt: Screen shot showing visualisation of the GGN using `pynml-plotmorph` +:align: center +:scale: 20 % + +Visualisation of the GGN using `pynml-plotmorph` +``` + +### Step 2) Adding biophysics to the GGN + +Now that we have the morphology of the GGN exported, we can add the biophysics. +We need to inspect the original model code to learn about the biophysics. +In this model, for the GGN cell, the biophysics are included in the HOC script: + +```{code-block} +proc biophys() { + forsec all { + Ra = 100.0 + cm = 1 + insert pas + g_pas = 0.03e-3 // S/cm2 - as per Laurent et al 1990 RM = 33kohm-cm2 + e_pas = -51 + } +} + +``` + +As we see here, this is a passive cell without any ion channels. +To add the biophysics, we write a simple Python script that will make use of the pyNeuroML API. +The complete script is present in the [repository](https://github.com/OpenSourceBrain/262670/blob/master/NeuroML2/postprocess_cells.py): + +```{code-block} python +def load_and_setup_cell(cellname: str): + """Load a cell, and clean it to prepare it for further modifications. + + These operations are common for all cells. + + :param cellname: name of cell. + the file containing the cell should then be .morph.cell.nml + :returns: document with cell + :rtype: neuroml.NeuroMLDocument + + """ + celldoc = read_neuroml2_file( + f"{cellname}.morph.cell.nml" + ) # type: neuroml.NeuroMLDocument + cell = celldoc.cells[0] # type: neuroml.Cell + celldoc.networks = [] + cell.id = cellname + cell.notes = cell.notes.replace("GGN_20170309_sc_0_0", cellname) + cell.notes += ". Reference: Subhasis Ray, Zane N Aldworth, Mark A Stopfer (2020) Feedback inhibition and its control in an insect olfactory circuit eLife 9:e53281." + + [ + default_all_group, + default_soma_group, + default_dendrite_group, + default_axon_group, + ] = cell.setup_default_segment_groups( + use_convention=True, + default_groups=["all", "soma_group", "dendrite_group", "axon_group"], + ) + + # populate default groups + for sg in cell.morphology.segment_groups: + if "soma" in sg.id and sg.id != "soma_group": + default_soma_group.add(neuroml.Include(segment_groups=sg.id)) + if "axon" in sg.id and sg.id != "axon_group": + default_axon_group.add(neuroml.Include(segment_groups=sg.id)) + if "dend" in sg.id and sg.id != "dendrite_group": + default_dendrite_group.add(neuroml.Include(segment_groups=sg.id)) + + cell.optimise_segment_groups() + + return celldoc + + +def postprocess_GGN(): + """Post process GGN and add biophysics.""" + cellname = "GGN" + celldoc = load_and_setup_cell(cellname) + cell = celldoc.cells[0] # type: neuroml.Cell + + # biophysics + # all + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="pas", + ion_channel="pas", + cond_density="0.00003 S_per_cm2", + erev="-51 mV", + group_id="all", + ion="non_specific", + ion_chan_def_file="channels/pas.channel.nml", + ) + cell.set_resistivity("0.1 kohm_cm", group_id="all") + cell.set_specific_capacitance("1 uF_per_cm2", group_id="all") + cell.set_init_memb_potential("-80mV") + + # L1 validation + # cell.validate(recursive=True) + cell.summary(morph=False, biophys=True) + # use pynml writer to also run L2 validation + write_neuroml2_file(celldoc, f"{cellname}.cell.nml") + +``` + +The `load_and_setup_cell` function does some basic clean up and set up of the cell. +It ensures that the various segments that were exported from NEURON are placed into the conventional segment groups. +The `postprocess_GGN` function then adds the passive biophysics to the cell. + +The `pas` channel is a standard implementation of a passive ion channel. +The rest are membrane properties--resistivity, specific capacitance and so on. +Once this is set up, we write the cell to a new file. + +The GGN cell has now been converted. +Since the GGN is a simple passive cell, we won't test its biophysics just yet. + +## Converting the Kenyon Cell + +The KC cell is defined in the `kc_1_comp.hoc` file. +Whereas the GGN cell had a complex morphology but passive biophysics, the KC cell has very simple morphology---a single compartment---but does contain active channels: + +```{code-block} +create soma + + +objref all +proc subsets() { local i + objref all + all = new SectionList() + soma all.append() +} +proc geom() { + soma { // Total Cm = 4 pF + L = 6.366 + diam = 20 + } +} + +proc biophys() { + forsec all { + Ra = 35.4 + cm = 1 + insert pas + g_pas = 9.75e-5 // S/cm2 + e_pas = -70 // mV + insert kv + gbar_kv = 1.5e-3 // S/cm2 + insert ka + gbar_ka = 1.4525e-2 // S/cm2 + insert kst + gbar_kst = 2.0275e-3 // S/cm2 + insert naf + gbar_naf = 3.5e-2 // S/cm2 + insert nas + gbar_nas = 3e-3 // S/cm2 + ek = -81.0 // mV + ena = 58.0 // mV + } +} + +``` + +### Step 1) Converting ion channels + +For this cell, we will first convert the various ion channel models. +These are included in the `mod` folder. +An inspection tells us that these are all Hodgkin-Huxley type ion channels that use similar formalisms. + +The first thing to do is to generate plots of time courses and steady states of the various ion channels. +These can be done easily using `pynml-modchananalysis` command line tool included in pyNeuroML. +We begin with the `nas` channel: + +```{code-block} +pynml-modchananalysis -modFile nas_wustenberg.mod nas +``` + +This will generate two plots, one for the steady state dynamics (`inf`), and one for the time course (`tau`) for activation variables in the channels: + +```{figure} ../../../images/Time_course(s)_of_activation_variables_in_nas_at_6.3_degC.png +:alt: Image showing time course of activation variables of nas channel, generated with pynml-modchananalysis +:align: center +:scale: 40 % + +Time course of activation variables of nas channel, generated with pynml-modchananalysis +``` + +```{figure} ../../../images/Steady_state(s)_of_activation_variables_in_nas_at_6.3_degC.png +:alt: Image showing steady state dynamics of activation variables of nas channel, generated with pynml-modchananalysis +:align: center +:scale: 40 % + +Steady state dynamics of activation variables of nas channel, generated with pynml-modchananalysis +``` +The mod file defining the nas channel is shown below: + +```{literalinclude} ./scripts/nas_wustenberg.mod +``` + +Here we have the `m` and `h` activation variables. +Although they are described in the standard Hodgkin Huxley formalism, in the `settables` procedure, we can see that their values are only calculated in the range of -120mV to 40mV. +The value does not change beyond 40mV. +This could be done for a number of reasons. +Perhaps the cell's membrane potential does not go beyond 40mV. + +We will attempt to remain faithful to the mod file in our conversion, so we will also incorporate this feature. + +Since we know this is a Hodgkin Huxley type channel, we can search the schema to see if there are any elements that can describe it. +A search shows us that the [ionChannelHH](https://docs.neuroml.org/Userdocs/Schemas/Channels.html#ionchannelhh) component type exists in the schema/standard. +In the schema, this is identical to [ionChannel](https://docs.neuroml.org/Userdocs/Schemas/Channels.html#ionchannel). +The usage examples included in the documentation indicate that we can use these elements from the standard to describe the ion channel here. +We need to: + +- include the `m` gate, which has 3 sub units (`m^3`) +- include the `h` gate, which has 1 sub unit (`h^1`) +- formalise the equations that are used to calculate the steady state (`inf`)and time course (`tau`) for these gates/activation variables. + +To begin with, let us ignore the restriction included in the mod file at 40mV. +Our NeuroML description will look something like this: + +```{code-block} xml + + + + +
+``` + +Now, there are number of different ways of expressing the dynamics of the activation variables. +(See [this page for an introduction to HH formalism](https://www.st-andrews.ac.uk/~wjh/hh_model_intro/)). +One can use the values of the forward and reverse rates (called `alpha` and `beta` in general) to calculate the steady state and time course. +Another possibility is that `alpha` and `beta` are not given, and instead the equations for the steady state and time course are. +The latter is the case here: + +``` +inf = 1 / ( 1 + exp((Vh - V) / s) ) +``` + +If the rates are given, one can use the [gateHHrates](https://docs.neuroml.org/Userdocs/Schemas/Channels.html#gatehhrates) component type from the standard. +If the steady state and time course are, we can use [gateHHtauInf](https://docs.neuroml.org/Userdocs/Schemas/Channels.html#gatehhtauinf). +There are also other components that can be used if a combination of rates and/or steady state and time course are given. + +The equation above is in the form of a [sigmoid function](https://en.wikipedia.org/wiki/Sigmoid_function). +Another search in the standard shows us that we have the [HHSigmoidVariable](https://docs.neuroml.org/Userdocs/Schemas/Channels.html#hhsigmoidvariable) component type that can be used to represent a rate that is a sigmoid function. +The `dynamics` tab tells us that the equation is represented as: + +``` +x = rate / (1 + exp(0 - (v - midpoint)/scale)) +``` + +Putting the equation for `minf` and `hinf` together with this form: + +``` +x = rate / (1 + exp(0 - (v - midpoint)/scale)) +minf = 1.0 / (1 + exp((-30.1 - v) / 6.65)) +hinf = 1.0 / (1 + exp((v + 51.4) / 5.9 )) +``` +We can see that for `minf`, `rate = 1 per ms`, `scale = 6.65mV` and `midpoint = -30.1mV`. +Similarly, for `hinf`, `rate = 1 per ms`, `scale = -5.9mV` and `midpoint = -51.4mV`. + +```{code-block} xml + + + + + + + + + + + + +``` + +The time course is given by: +``` +taum = (taumax - taumin) / (1 + exp((V - Vh1) / s1)) + taumin +``` +Even though this is also a sigmoid, it is not, unfortunately, a standard form. +A component type does not exist in the NeuroML standard that can encapsulate this form +(It has more parameters, and has an additional `+ taumin`). + +This is not a problem, though, because NeuroML can be easily extended using {ref}`LEMS `. +We can write a new component type to encapsulate these dynamics based on the [LEMS definition](https://github.com/NeuroML/NeuroML2/blob/development/NeuroML2CoreTypes/Channels.xml#L99) of the [HHSigmoidVariable](https://docs.neuroml.org/Userdocs/Schemas/Channels.html#hhsigmoidvariable) component type: + +```{code-block} xml + + + + + +``` + +Our new component will be this, and we will save it in a different file that we can then "include" in the nas channel definition file: + +```{code-block} xml + + + + + + + + + + + + + + + +``` + +Note that it is very similar to the HHSigmoidVariable definition. +The only difference is that we have had to define additional parameters to use in our equation. +Also note that `HHSigmoidVariable` extends `baseHHVariable` which extends `baseVoltageDepVariable`. +However, since we know that `tau` is a time value, we extend the `baseVoltageDepTime` component type instead. +This is very similar to `baseVoltageDepVariable`, but is designed for component types producing time values, such as the time course here. + +We save this as a different component type (a class), and we will provide it parameters to create our time courses for both `m` and `h` activation variables. +Our completed file will look like this: + +```{code-block} xml + + + + + NeuroML file containing a single ion channel + + + + + + + + + + + + + + + + +``` + +Running `pynml-channelanalysis nas.nml` will generate the graphs for the steady state and time course from our channel definition, and you will see that these are the same as the graphs we generated from the mod files. + + +We are almost there, but we have a little more work to do here. +Remember that the original mod file limited the value of steady state at 40mV? +We have not incorporated that into our channel file yet. + +Since the `HHSigmoidVariable` we have used for the steady state does not allow multiple equations, we will write a new component type for the steady state also: + +```{code-block} xml + + + + + + + + + + + + + + + + + +``` + +The only difference here is that instead of the `DerivedVariable`, we have used a `ConditionalDerivedVariable` that allows conditional dynamics. +We have two cases here: +- if `v` is greater than `table_max` (which is 40mV), the rate is the value at `v=40mV` +- otherwise, the rate is calculated from the value of `v` + +#### 1a) Kv, Naf, Kst + +The nas channel is now done. +If we look at the other channels---naf, kv, and kst---they follow similar formalisms. +So, we can re-use our newly created component types, `Ray_inf` and `Ray_tau`. +In fact, we consolidate them in a single file, `RaySigmoid.nml`, and "include" this in the channel definition files. +For example, here is `kv.channel.nml`: + +```{code-block} xml + + + + NeuroML file containing a single ion channel + + + + + + Implementation of A type K+ channel ( KV ) from Wustenberg DG, Boytcheva M, Grunewald B, Byrne JH, Menzel R, Baxter DA. + This is a delayed rectifier type K+ channel in Apis mellifera Kenyon cells (cultured). + + + + + + + + + + +``` + +Plots for the steady state and time course are: + +```{figure} ../../../images/Steady_state(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png +:alt: Image showing steady state dynamics of activation variables of kv channel, generated with pynml-channelanalysis +:align: center +:scale: 40 % + +Steady state dynamics of activation variables of kv channel, generated with pynml-channelanalysis +``` + +```{figure} ../../../images/Time_Course(s)_of_activation_variables_of_kv_from_kv.channel.nml_at_6.3_degC.png +:alt: Image showing time course of activation variables of kv channel, generated with pynml-channelanalysis +:align: center +:scale: 40 % + +Time course of activation variables of kv channel, generated with pynml-channelanalysis +``` + +In these graphs, the effect of the conditional at 40mV becomes more apparent. + +#### 1b) Ka + +The last remaining channel is the ka channel. +It's dynamics are defined in the mod file as: + +```{code-block} +PROCEDURE settables(v (mV)) { +UNITSOFF + TABLE minf, hinf, mtau, htau FROM -120 TO 40 WITH 641 + minf = 1.0 / (1 + exp((-20.1 - v)/16.1)) + hinf = 1.0 / ( 1 + exp( ( v + 74.7 ) / 7 ) ) + mtau = (1.65 - 0.35) / ((1 + exp(- (v + 70) / 4.0)) * (1 + exp((v + 20) / 12.0))) + 0.35 + htau = (90 - 2.5) / ((1 + exp(- (v + 60) / 25.0)) * (1 + exp((v + 62) / 16.0))) + 2.5 +UNITSON +} +``` +The steady state here follows the same formalism, but the time course does not. +So, we need to create new component type to encapsulate the time courses here, similar to the `Ray_tau` component type that we did before: + +```{code-block} xml + + + + + + + + + + + + + + + + + + +``` +We also add this to our `RaySigmoid.nml` file. +The ka.channel.nml file will, finally, look like this: + +```{code-block} xml + + + + NeuroML file containing a single ion channel + + + + + + Implementation of A type K+ channel ( KA ) from Wustenberg DG, Boytcheva M, Grunewald B, Byrne JH, Menzel R, Baxter DA. + This is transient A type K+ channel in Apis mellifera Kenyon cells (cultured). + + + + + + + + + + + + + + + +``` + +That is all the ion channels converted. + +The ion channels are usually the most involved to convert because one must understand their initial descriptions in the mod files. +Even though the [NMODL language](https://nrn.readthedocs.io/en/8.2.2/python/modelspec/programmatic/mechanisms/nmodl.html#nmodl) used in mod files does have a well defined structure, like general programming languages, it is free-flowing. +This means that different people can write the same dynamics in different ways. +On the other hand, NeuroML and LEMS are more formal with more strict structures, and once channels are converted to these formats, they are much easier to understand. + +### Step 2) Creating the morphology + +Since the morphology of the KC is a single compartment, we don't need to export it from NEURON. +We can create it ourselves. + +The morphology is given in the HOC script: + +```{code-block} +proc geom() { + soma { // Total Cm = 4 pF + L = 6.366 + diam = 20 + } +} +``` + +We can create this using a Python script: + +```{code-block} python + celldoc = component_factory( + "NeuroMLDocument", id="KC_doc" + ) # type: neuroml.NeuroMLDocument + cell = celldoc.add("Cell", id="KC", validate=False) # type: neuroml.Cell + cell.setup_nml_cell() + cell.add_segment([0, 0, 0, 20], [0, 0, 6.366, 20], seg_type="soma") +``` + +The `setup_nml_cell` and `add_segment` methods are part of the [Cell class in the standard API](https://libneuroml.readthedocs.io/en/latest/userdocs/coreclasses.html#cell). + +Now that we have the morphology and the ion channels for the KC, we can add the biophysics to the morphology to complete the cell: + +```{code-block} python + # biophysics + # all + cell.set_resistivity("35.4 ohm_cm", group_id="all") + cell.set_specific_capacitance("1 uF_per_cm2", group_id="all") + cell.set_init_memb_potential("-70mV") + cell.set_spike_thresh("-10mV") + + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="pas", + ion_channel="pas", + cond_density="9.75e-5 S_per_cm2", + erev="-70 mV", + group_id="all", + ion="non_specific", + ion_chan_def_file="channels/pas.channel.nml", + ) + + # K + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="kv", + ion_channel="kv", + cond_density="1.5e-3 S_per_cm2", + erev="-81 mV", + group_id="all", + ion="k", + ion_chan_def_file="channels/kv.channel.nml", + ) + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="ka", + ion_channel="ka", + cond_density="1.4525e-2 S_per_cm2", + erev="-81 mV", + group_id="all", + ion="k", + ion_chan_def_file="channels/ka.channel.nml", + ) + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="kst", + ion_channel="kst", + cond_density="2.0275e-3 S_per_cm2", + erev="-81 mV", + group_id="all", + ion="k", + ion_chan_def_file="channels/kst.channel.nml", + ) + # Na + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="naf", + ion_channel="naf", + cond_density="3.5e-2 S_per_cm2", + erev="58 mV", + group_id="all", + ion="na", + ion_chan_def_file="channels/naf.channel.nml", + ) + cell.add_channel_density( + nml_cell_doc=celldoc, + cd_id="nas", + ion_channel="nas", + cond_density="3e-3 S_per_cm2", + erev="58 mV", + group_id="all", + ion="na", + ion_chan_def_file="channels/nas.channel.nml", + ) +``` + +This completes the cell. +We export it to a NeuroML file. + +### Step 3) Testing the model + +Finally, we want to test our NeuroML conversion against the original cell to see that it exhibits the same dynamics. +The `test_kc.py` script runs a simple step current simulation with a single KC cell and shows its membrane potentials: + +```{figure} ../../../images/KC-NEURON.png +:alt: Image showing the membrane potential of the NEURON implementation of the KC cell model with a step current. +:align: center +:scale: 40 % + +The membrane potential of the NEURON implementation of the KC cell model with a step current. +``` + + +We write a quick simulation to reproduce these using our NeuroML model: + +```{code-block} python +def step_current_omv_kc(): + """Create a step current simulation OMV LEMS file""" + # read the cell file, modify it, write a new one + netdoc = read_neuroml2_file("KC.cell.nml") + kc_cell = netdoc.cells[0] + net = netdoc.add(neuroml.Network, id="KC_net", validate=False) + pop = net.add(neuroml.Population, id="KC_pop", component=kc_cell.id, size=1) + + # should be same as test_kc.py + pg = netdoc.add( + neuroml.PulseGenerator( + id="pg", delay="100ms", duration="500ms", + amplitude="16pA" + ) + ) + + # Add these to cells + input_list = net.add( + neuroml.InputList(id="input_list", component=pg.id, populations=pop.id) + ) + aninput = input_list.add( + neuroml.Input( + id="0", + target="../%s[0]" % (pop.id), + destination="synapses", + segment_id="0", + ) + ) + write_neuroml2_file(netdoc, "KC.net.nml") + + generate_lems_file_for_neuroml( + sim_id="KC_step_test", + target=net.id, + neuroml_file="KC.net.nml", + duration="700ms", + dt="0.01ms", + lems_file_name="LEMS_KC_step_test.xml", + nml_doc=netdoc, + gen_spike_saves_for_all_somas=True, + target_dir=".", + gen_saves_for_quantities={ + "k.dat": ["KC_pop[0]/biophys/membraneProperties/kv/iDensity"] + }, + copy_neuroml=False + ) + + data = run_lems_with_jneuroml_neuron( + "LEMS_KC_step_test.xml", load_saved_data=True, compile_mods=True + ) + + generate_plot( + xvalues=[data["t"]], + yvalues=[data["KC_pop[0]/v"]], + title="Membrane potential: KC", + ) +``` + +This will generate graphs of the KC's membrane potential. +```{figure} ../../../images/KC-NeuroML.png +:alt: Image showing the membrane potential of the NeuroML implementation of the KC cell model with a step current. +:align: center +:scale: 40 % + +The membrane potential of the NeuroML implementation of the KC cell model with a step current. +``` + +As we can see, the membrane potentials look very similar. +In the next page, we will also set up some more validation tests to better verify that the NEURON and NeuroML implementations produce the same dynamics. + +Since this writes a LEMS simulation file also, we can also run the LEMS file directly for later verification: + +``` +pynml LEMS_KC_step_test.xml -neuron -nogui +``` diff --git a/_sources/Userdocs/Walkthroughs/RayEtAl2020/OMV.md b/_sources/Userdocs/Walkthroughs/RayEtAl2020/OMV.md new file mode 100644 index 00000000..424acc6d --- /dev/null +++ b/_sources/Userdocs/Walkthroughs/RayEtAl2020/OMV.md @@ -0,0 +1,226 @@ +# Adding OMV tests + +Now that we have converted the cell models to NeuroML, we want to ensure that we get the same behaviour from the NeuroML converted cell model as from the original NEURON code. +For this, we have the [Open Source Model Validation (OMV) framework](https://github.com/OpenSourceBrain/osb-model-validation/). +The idea here is that we write simple test files that `omv` will run, and we provide data that `omv` can check against to see if the tests results are correct. + +We will add OMV tests for the KC here. + +## Step 1) Getting spike data from the NEURON model + +For `omv` to test the model against, we need to generate some spike data that it knows to be the expected values. +The `test_kc.py` script already provides us with the spike data. +So, we can run the script and note down the spike times in a Model Emergent Properties (MEP) file: + +```{code-block} yaml +system: Testing a detailed cell + +experiments: + stepKC: + expected: + spike times: [144.45000000000556, 177.64999999997536, 210.29999999994567, 242.74999999991616, 275.0499999998868, 307.19999999985754, 339.2249999998284, 371.07499999979945, 402.74999999977064, 434.1499999997421, 465.2249999997138, 495.87499999968594, 525.9749999997221, 555.3499999998289, 583.8499999999326] + +# generated from test-kc.py +``` + +## Step 2) Adding tests +Next, we can write a OSB Model Test (OMT) file to test the model using the step current simulation we had written before: + + +```{code-block} yaml +target: LEMS_KC_step_test.xml +engine: jNeuroML_NEURON +mep: .test.kc.mep +experiments: + stepKC: + observables: + spike times: + file: + path: KC_step_test.KC_pop.v.dat + columns: [0,1] + scaling: [1000,1000] + spike detection: + method: threshold + threshold: -10. + tolerance: 0.00 +``` + + +Note that we start with a tolerance of 0 here. +Let us run the test and see what we get: + +```{code-block} console +$ omv test .test.kc.jnmlneuron.omt + +[omv] +[omv] Running the tests defined in .test.kc.jnmlnrn.omt +[omv] ================================================= +[omv] Found 1 experiment(s) to run on engine: jNeuroML_NEURON +[omv] PATH: :/home/asinha/.local/share/virtualenvs/neuroml-311-dev/bin +[omv] Env vars: {'PYTHONPATH': '/home/asinha/local/lib/python/site-packages', 'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')} +[omv] Running file ./LEMS_KC_step_test.xml with jNeuroML_NEURON, env: {'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')} +[omv] Running the commands: [/usr/bin/jnml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml -neuron -nogui -run] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}) +[omv] Commands: ['/usr/bin/jnml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml', '-neuron', '-nogui', '-run'] completed successfully +[omv] Success with running jNeuroML_NEURON +[omv] Running checks for experiment: stepKC +[omv] +[omv] Comparison of + (observed data): [143.95, 176.76, 209.23, 241.52, 273.66, 305.68, 337.57, 369.33, 400.94, 432.38, 463.62, 494.59999999999997, 525.28, 555.59, 585.45] + and + (expected data): [144.45000000000556, 177.64999999997536, 210.29999999994567, 242.74999999991616, 275.0499999998868, 307.19999999985754, 339.2249999998284, 371.07499999979945, 402.74999999977064, 434.1499999997421, 465.2249999997138, 495.87499999968594, 525.9749999997221, 555.3499999998289, 583.8499999999326] + failed against tolerance 0 +[omv] A better tolerance to try is: 0.005087969567027844 +[omv] Observable Test Passed +[omv] -------------------------------------------------- +[omv] spike times ✘ +[omv] +++++++++++++++++++++ Error info ++++++++++++++++++ +[omv] Return code: 0 +``` + +We see that there's a slight difference in the spike times we obtain from our implementation. +This is not unexpected. +Small variations in how the mod files are written, or how the morphology is set up can result in small variations in the spike times. +`omv` will suggest a tolerance value for us to use. +The smaller the tolerance, the better. + +We update our file to use the suggested tolerance and re-run the test: + +```{code-block} console +$ omv test .test.kc.jnmlnrn.omt +[omv] +[omv] Running the tests defined in .test.kc.jnmlnrn.omt +[omv] ================================================= +[omv] Found 1 experiment(s) to run on engine: jNeuroML_NEURON +[omv] PATH: :/home/asinha/.local/share/virtualenvs/neuroml-311-dev/bin +[omv] Env vars: {'PYTHONPATH': '/home/asinha/local/lib/python/site-packages', 'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')} +[omv] Running file ./LEMS_KC_step_test.xml with jNeuroML_NEURON, env: {'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')} +[omv] Running the commands: [/usr/bin/jnml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml -neuron -nogui -run] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}) +[omv] Commands: ['/usr/bin/jnml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml', '-neuron', '-nogui', '-run'] completed successfully +[omv] Success with running jNeuroML_NEURON +[omv] Running checks for experiment: stepKC +[omv] +[omv] Observable Test Passed +[omv] -------------------------------------------------- +[omv] spike times ✔ +[omv] +[omv] ================================= +[omv] Test passed: .test.kc.jnmlnrn.omt +``` + +We can also add a simple validation test that will allow `omv` to validate the various NeuroML files in the repository: + +```{code-block} yaml +target: "*.c*.nml" +engine: jNeuroML_validate +``` + +One can run all the OMV tests in a repository at once: + +```{code-block} console +$ omv all +[omv] Python 3. Ignoring tests for non Py3 compatible engines: False +[omv] +[omv] +[omv] Running the tests defined in ./.test.kc.jnmlnrn.omt +[omv] =================================================== +[omv] Found 1 experiment(s) to run on engine: jNeuroML_NEURON +[omv] PATH: :/home/asinha/.local/share/virtualenvs/neuroml-311-dev/bin +[omv] Env vars: {'PYTHONPATH': '/home/asinha/local/lib/python/site-packages', 'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')} +[omv] Running file ./LEMS_KC_step_test.xml with jNeuroML_NEURON, env: {'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')} +[omv] Running the commands: [/usr/bin/jnml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml -neuron -nogui -run] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'NEURON_HOME': '/home/asinha/.local/share/virtualenvs/neuroml-311-dev', 'JNML_HOME': PosixPath('/usr/bin')}) +[omv] Commands: ['/usr/bin/jnml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/LEMS_KC_step_test.xml', '-neuron', '-nogui', '-run'] completed successfully +[omv] Success with running jNeuroML_NEURON +[omv] Running checks for experiment: stepKC +[omv] +[omv] Observable Test Passed +[omv] -------------------------------------------------- +[omv] spike times ✔ +[omv] +[omv] +[omv] [ Test 1 of 2 complete - failed so far: 0 ] +[omv] +[omv] +[omv] Running the tests defined in ./.test.validate.omt +[omv] ================================================= +[omv] No mep file specified. Will only run simulation using: jNeuroML_validate +[omv] Found 1 experiment(s) to run on engine: jNeuroML_validate +[omv] Running with jNeuroML_validate, using: ['/usr/bin/jnml', '-validate', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.morph.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/KC.cell.nml']... +[omv] Running the commands: [/usr/bin/jnml -validate /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.morph.cell.nml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.cell.nml /home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/KC.cell.nml] in (/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; cwd=/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2; shell=False; env={'JNML_HOME': PosixPath('/usr/bin')}) +[omv] Commands: ['/usr/bin/jnml', '-validate', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.morph.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/GGN.cell.nml', '/home/asinha/Documents/02_Code/00_mine/models/RayEtAl2020/NeuroML2/KC.cell.nml'] completed successfully +[omv] Running checks for experiment: Dry run +[omv] +[omv] Observable Test Passed +[omv] -------------------------------------------------- +[omv] dry ✔ +[omv] +[omv] +[omv] [ Test 2 of 2 complete - failed so far: 0 ] +[omv] +[omv] ------------- +[omv] 2 test(s) run +[omv] ------------- +[omv] +[omv] All tests passing! +[omv] ================== + +``` + +## Step 3) Setting up continuous testing on GitHub Actions + +Now that we have set up OMV test, we want to set up ["continuous testing" (CT)](https://en.wikipedia.org/wiki/Continuous_testing). +What this means is that we want these test to run automatically whenever we make any changes. +On GitHub, we can do these using [GitHub Actions](https://docs.github.com/en/actions). + +To set up a GitHub Action, we need to set up a "workflow file" in the `.github/workflows` directory. +We create one called `omv-ci.yml`: + +```{code-block} yaml + +name: Continuous build using OMV + +on: + schedule: + - cron: "1 1 1 */2 *" + push: + branches: [ master, development, experimental ] + pull_request: + branches: [ master, development, experimental ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: [ "3.8", "3.10"] + engine: [ jNeuroML_validate, jNeuroML_NEURON ] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install OMV + run: | + pip install OSBModelValidation + pip install scipy sympy matplotlib cython pandas tables + + - name: Run OMV tests on engine ${{ matrix.engine }} + run: | + omv all -V --engine=${{ matrix.engine }} + + - name: OMV final version info + run: | + omv list -V # list installed engines + env +``` + +This installs OMV and runs all test using it in the repository. +Additionally, it tests this out on a couple of Python versions. + +Now, whenever we make a change to the repository---either as a pull request, or as a direct push of a commit, these tests will be run immediately to tell us if the model is still working as it should. +These can be seen in the ["actions" tab in the GitHub Repository](https://github.com/OpenSourceBrain/262670/actions). diff --git a/_sources/Userdocs/Walkthroughs/RayEtAl2020/RayEtAl2020.md b/_sources/Userdocs/Walkthroughs/RayEtAl2020/RayEtAl2020.md new file mode 100644 index 00000000..f28f4654 --- /dev/null +++ b/_sources/Userdocs/Walkthroughs/RayEtAl2020/RayEtAl2020.md @@ -0,0 +1,8 @@ +(userdocs:walkthroughs:rayetal2020)= +# Converting Ray et al 2020 to NeuroML + +This section documents the conversion of Ray et al 2020 {cite}`Ray2020`, which was originally implemented in NEURON, to NeuroML. +It broadly follows the steps outlined in the {ref}`converting models ` section. + +For any queries, please contact Ankur Sinha on any of the NeuroML channels. + diff --git a/_sources/Userdocs/Walkthroughs/RayEtAl2020/Setup.md b/_sources/Userdocs/Walkthroughs/RayEtAl2020/Setup.md new file mode 100644 index 00000000..afe0dbea --- /dev/null +++ b/_sources/Userdocs/Walkthroughs/RayEtAl2020/Setup.md @@ -0,0 +1,30 @@ +# Setting up + +## Step 1) Find the original model code + +The original code is published on [ModelDB](https://modeldb.science/262670). + +## Step 2) Create GitHub and Open Source Brain accounts for sharing the code + +### 2a) Sign up to GitHub and Open Source Brain + +We signed in to GitHub and OSBv1 + +### 2b) Create GitHub repository + +ModelDB provides GitHub repositories for all its models now. +This model is available on GitHub here: https://github.com/ModelDBRepository/262670. +The Open Source Brain (OSB) organization on GitHub also keeps a "fork" of these repositories to allow users to easily add them to both Open Source Brain v1 and v2. +This fork is here, and is the one that we will work with: https://github.com/OpenSourceBrain/262670. + +For the conversion, I (Ankur) created a fork of this repository with a new branch to work in: https://github.com/sanjayankur31/262670. +A pull request work flow was used to submit converted bits back to the repository. + +The first step was to re-organise the code to prepare it for conversion. +All the existing code was moved to a new NEURON folder, and a new NeuroML2 folder set up to store the NeuroML version. + +### 2c) Create Open Source Brain project + +A new project was created on OSBv1 and linked to the OSB repository: https://v1.opensourcebrain.org/projects/locust-mushroom-body. + + diff --git a/_sources/Userdocs/Walkthroughs/Walkthroughs.md b/_sources/Userdocs/Walkthroughs/Walkthroughs.md new file mode 100644 index 00000000..855d5c21 --- /dev/null +++ b/_sources/Userdocs/Walkthroughs/Walkthroughs.md @@ -0,0 +1,4 @@ +(userdocs:walkthroughs)= +# Walk throughs + +This chapter documents a number of real-world tasks for users to refer to. diff --git a/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000..eb19f698 --- /dev/null +++ b/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_sphinx_design_static/design-tabs.js b/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000..36b38cf0 --- /dev/null +++ b/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/NeuroML2012/DWaltemath_sed-ml_edinburgh2012_.pdf b/_static/NeuroML2012/DWaltemath_sed-ml_edinburgh2012_.pdf new file mode 100644 index 00000000..bcfcbbbe Binary files /dev/null and b/_static/NeuroML2012/DWaltemath_sed-ml_edinburgh2012_.pdf differ diff --git a/_static/NeuroML2012/JKozloski_NeuroML_workshop_2012.pdf b/_static/NeuroML2012/JKozloski_NeuroML_workshop_2012.pdf new file mode 100644 index 00000000..79ebaed6 Binary files /dev/null and b/_static/NeuroML2012/JKozloski_NeuroML_workshop_2012.pdf differ diff --git a/_static/NeuroML2012/MHull_NineML.pdf b/_static/NeuroML2012/MHull_NineML.pdf new file mode 100644 index 00000000..0ac42c5d Binary files /dev/null and b/_static/NeuroML2012/MHull_NineML.pdf differ diff --git a/_static/NeuroML2012/NeuroLexNIFupdate_3-13-12.ppt b/_static/NeuroML2012/NeuroLexNIFupdate_3-13-12.ppt new file mode 100644 index 00000000..7b75dd71 Binary files /dev/null and b/_static/NeuroML2012/NeuroLexNIFupdate_3-13-12.ppt differ diff --git a/_static/NeuroML2012/NleNovere_NeuroML-COMBINE.pdf b/_static/NeuroML2012/NleNovere_NeuroML-COMBINE.pdf new file mode 100644 index 00000000..bceb99b7 Binary files /dev/null and b/_static/NeuroML2012/NleNovere_NeuroML-COMBINE.pdf differ diff --git a/_static/NeuroML2012/Open_Worm_03-13-12.ppt b/_static/NeuroML2012/Open_Worm_03-13-12.ppt new file mode 100644 index 00000000..ae344f0e Binary files /dev/null and b/_static/NeuroML2012/Open_Worm_03-13-12.ppt differ diff --git a/_static/NeuroML2012/PGleeson_NeuroMLIntro2012.ppt b/_static/NeuroML2012/PGleeson_NeuroMLIntro2012.ppt new file mode 100644 index 00000000..5d82e924 Binary files /dev/null and b/_static/NeuroML2012/PGleeson_NeuroMLIntro2012.ppt differ diff --git a/_static/NeuroML2012/RCannon_ModellingIonChannels.pdf b/_static/NeuroML2012/RCannon_ModellingIonChannels.pdf new file mode 100644 index 00000000..9594b24d Binary files /dev/null and b/_static/NeuroML2012/RCannon_ModellingIonChannels.pdf differ diff --git a/_static/NeuroML2012/RTomsett_LargeScaleCorticalModel.ppt b/_static/NeuroML2012/RTomsett_LargeScaleCorticalModel.ppt new file mode 100644 index 00000000..e35dfd19 Binary files /dev/null and b/_static/NeuroML2012/RTomsett_LargeScaleCorticalModel.ppt differ diff --git a/_static/NeuroML2012/SKeating_libsbml-and-sbml.pdf b/_static/NeuroML2012/SKeating_libsbml-and-sbml.pdf new file mode 100644 index 00000000..97ddd41c Binary files /dev/null and b/_static/NeuroML2012/SKeating_libsbml-and-sbml.pdf differ diff --git a/_static/NeuroML2012/YleFranc_CNO.pdf b/_static/NeuroML2012/YleFranc_CNO.pdf new file mode 100644 index 00000000..3dccb063 Binary files /dev/null and b/_static/NeuroML2012/YleFranc_CNO.pdf differ diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..2af6139e --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 270px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 00000000..92fad4b5 --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js new file mode 100644 index 00000000..54b3c463 --- /dev/null +++ b/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css new file mode 100644 index 00000000..f1916ec7 --- /dev/null +++ b/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 00000000..2ea7ff3e --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 00000000..dbe1aaad --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000..eb19f698 --- /dev/null +++ b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_static/design-tabs.js b/_static/design-tabs.js new file mode 100644 index 00000000..36b38cf0 --- /dev/null +++ b/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..4d67807d --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..dab586c0 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/favicon.ico b/_static/favicon.ico new file mode 100644 index 00000000..efdc1edf Binary files /dev/null and b/_static/favicon.ico differ diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/files/20231122-ACNet.webm b/_static/files/20231122-ACNet.webm new file mode 100644 index 00000000..e3c33a8d Binary files /dev/null and b/_static/files/20231122-ACNet.webm differ diff --git a/_static/files/20231122-HL23PYR.webm b/_static/files/20231122-HL23PYR.webm new file mode 100644 index 00000000..2f83a948 Binary files /dev/null and b/_static/files/20231122-HL23PYR.webm differ diff --git a/_static/files/NeuroMLEditorialBoardMeeting2014.pdf b/_static/files/NeuroMLEditorialBoardMeeting2014.pdf new file mode 100644 index 00000000..76b99828 Binary files /dev/null and b/_static/files/NeuroMLEditorialBoardMeeting2014.pdf differ diff --git a/_static/files/NeuroMLEditorialBoardMeeting2015.pdf b/_static/files/NeuroMLEditorialBoardMeeting2015.pdf new file mode 100644 index 00000000..396522a0 Binary files /dev/null and b/_static/files/NeuroMLEditorialBoardMeeting2015.pdf differ diff --git a/_static/files/NeuroMLEditorialBoardMeeting2016.pdf b/_static/files/NeuroMLEditorialBoardMeeting2016.pdf new file mode 100644 index 00000000..7b9a4b85 Binary files /dev/null and b/_static/files/NeuroMLEditorialBoardMeeting2016.pdf differ diff --git a/_static/files/NeuroMLEditorialBoardMeeting2018.pdf b/_static/files/NeuroMLEditorialBoardMeeting2018.pdf new file mode 100644 index 00000000..ee531a70 Binary files /dev/null and b/_static/files/NeuroMLEditorialBoardMeeting2018.pdf differ diff --git a/_static/files/NeuroMLEditorialBoardMeeting2019.pdf b/_static/files/NeuroMLEditorialBoardMeeting2019.pdf new file mode 100644 index 00000000..3ba314ed Binary files /dev/null and b/_static/files/NeuroMLEditorialBoardMeeting2019.pdf differ diff --git a/_static/files/NeuroMLWorkshop2009.pdf b/_static/files/NeuroMLWorkshop2009.pdf new file mode 100644 index 00000000..267795b2 Binary files /dev/null and b/_static/files/NeuroMLWorkshop2009.pdf differ diff --git a/_static/files/NeuroMLWorkshop2010.pdf b/_static/files/NeuroMLWorkshop2010.pdf new file mode 100644 index 00000000..caa28a80 Binary files /dev/null and b/_static/files/NeuroMLWorkshop2010.pdf differ diff --git a/_static/files/NeuroMLWorkshop2011.pdf b/_static/files/NeuroMLWorkshop2011.pdf new file mode 100644 index 00000000..a5d0a6f7 Binary files /dev/null and b/_static/files/NeuroMLWorkshop2011.pdf differ diff --git a/_static/files/neuroml-documentation.pdf b/_static/files/neuroml-documentation.pdf new file mode 100644 index 00000000..e797128a Binary files /dev/null and b/_static/files/neuroml-documentation.pdf differ diff --git a/_static/images/logo_binder.svg b/_static/images/logo_binder.svg new file mode 100644 index 00000000..45fecf75 --- /dev/null +++ b/_static/images/logo_binder.svg @@ -0,0 +1,19 @@ + + + + +logo + + + + + + + + diff --git a/_static/images/logo_colab.png b/_static/images/logo_colab.png new file mode 100644 index 00000000..b7560ec2 Binary files /dev/null and b/_static/images/logo_colab.png differ diff --git a/_static/images/logo_deepnote.svg b/_static/images/logo_deepnote.svg new file mode 100644 index 00000000..fa77ebfc --- /dev/null +++ b/_static/images/logo_deepnote.svg @@ -0,0 +1 @@ + diff --git a/_static/images/logo_jupyterhub.svg b/_static/images/logo_jupyterhub.svg new file mode 100644 index 00000000..60cfe9f2 --- /dev/null +++ b/_static/images/logo_jupyterhub.svg @@ -0,0 +1 @@ +logo_jupyterhubHub diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..367b8ed8 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/locales/ar/LC_MESSAGES/booktheme.mo b/_static/locales/ar/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..15541a6a Binary files /dev/null and b/_static/locales/ar/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ar/LC_MESSAGES/booktheme.po b/_static/locales/ar/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..edae2ec4 --- /dev/null +++ b/_static/locales/ar/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ar\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "موضوع بواسطة" + +msgid "Open an issue" +msgstr "افتح قضية" + +msgid "Contents" +msgstr "محتويات" + +msgid "Download notebook file" +msgstr "تنزيل ملف دفتر الملاحظات" + +msgid "Sphinx Book Theme" +msgstr "موضوع كتاب أبو الهول" + +msgid "Fullscreen mode" +msgstr "وضع ملء الشاشة" + +msgid "Edit this page" +msgstr "قم بتحرير هذه الصفحة" + +msgid "By" +msgstr "بواسطة" + +msgid "Copyright" +msgstr "حقوق النشر" + +msgid "Source repository" +msgstr "مستودع المصدر" + +msgid "previous page" +msgstr "الصفحة السابقة" + +msgid "next page" +msgstr "الصفحة التالية" + +msgid "Toggle navigation" +msgstr "تبديل التنقل" + +msgid "repository" +msgstr "مخزن" + +msgid "suggest edit" +msgstr "أقترح تحرير" + +msgid "open issue" +msgstr "قضية مفتوحة" + +msgid "Launch" +msgstr "إطلاق" + +msgid "Print to PDF" +msgstr "طباعة إلى PDF" + +msgid "By the" +msgstr "بواسطة" + +msgid "Last updated on" +msgstr "آخر تحديث في" + +msgid "Download source file" +msgstr "تنزيل ملف المصدر" + +msgid "Download this page" +msgstr "قم بتنزيل هذه الصفحة" diff --git a/_static/locales/bg/LC_MESSAGES/booktheme.mo b/_static/locales/bg/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..da951200 Binary files /dev/null and b/_static/locales/bg/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/bg/LC_MESSAGES/booktheme.po b/_static/locales/bg/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..1f363b9d --- /dev/null +++ b/_static/locales/bg/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bg\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Тема от" + +msgid "Open an issue" +msgstr "Отворете проблем" + +msgid "Contents" +msgstr "Съдържание" + +msgid "Download notebook file" +msgstr "Изтеглете файла на бележника" + +msgid "Sphinx Book Theme" +msgstr "Тема на книгата Sphinx" + +msgid "Fullscreen mode" +msgstr "Режим на цял екран" + +msgid "Edit this page" +msgstr "Редактирайте тази страница" + +msgid "By" +msgstr "От" + +msgid "Copyright" +msgstr "Авторско право" + +msgid "Source repository" +msgstr "Хранилище на източника" + +msgid "previous page" +msgstr "предишна страница" + +msgid "next page" +msgstr "Следваща страница" + +msgid "Toggle navigation" +msgstr "Превключване на навигацията" + +msgid "repository" +msgstr "хранилище" + +msgid "suggest edit" +msgstr "предложи редактиране" + +msgid "open issue" +msgstr "отворен брой" + +msgid "Launch" +msgstr "Стартиране" + +msgid "Print to PDF" +msgstr "Печат в PDF" + +msgid "By the" +msgstr "По" + +msgid "Last updated on" +msgstr "Последна актуализация на" + +msgid "Download source file" +msgstr "Изтеглете изходния файл" + +msgid "Download this page" +msgstr "Изтеглете тази страница" diff --git a/_static/locales/bn/LC_MESSAGES/booktheme.mo b/_static/locales/bn/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..6b96639b Binary files /dev/null and b/_static/locales/bn/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/bn/LC_MESSAGES/booktheme.po b/_static/locales/bn/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..fa543728 --- /dev/null +++ b/_static/locales/bn/LC_MESSAGES/booktheme.po @@ -0,0 +1,63 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bn\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "থিম দ্বারা" + +msgid "Open an issue" +msgstr "একটি সমস্যা খুলুন" + +msgid "Download notebook file" +msgstr "নোটবুক ফাইল ডাউনলোড করুন" + +msgid "Sphinx Book Theme" +msgstr "স্পিনিক্স বুক থিম" + +msgid "Edit this page" +msgstr "এই পৃষ্ঠাটি সম্পাদনা করুন" + +msgid "By" +msgstr "দ্বারা" + +msgid "Copyright" +msgstr "কপিরাইট" + +msgid "Source repository" +msgstr "উত্স সংগ্রহস্থল" + +msgid "previous page" +msgstr "আগের পৃষ্ঠা" + +msgid "next page" +msgstr "পরবর্তী পৃষ্ঠা" + +msgid "Toggle navigation" +msgstr "নেভিগেশন টগল করুন" + +msgid "open issue" +msgstr "খোলা সমস্যা" + +msgid "Launch" +msgstr "শুরু করা" + +msgid "Print to PDF" +msgstr "পিডিএফ প্রিন্ট করুন" + +msgid "By the" +msgstr "দ্বারা" + +msgid "Last updated on" +msgstr "সর্বশেষ আপডেট" + +msgid "Download source file" +msgstr "উত্স ফাইল ডাউনলোড করুন" + +msgid "Download this page" +msgstr "এই পৃষ্ঠাটি ডাউনলোড করুন" diff --git a/_static/locales/ca/LC_MESSAGES/booktheme.mo b/_static/locales/ca/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..a4dd30e9 Binary files /dev/null and b/_static/locales/ca/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ca/LC_MESSAGES/booktheme.po b/_static/locales/ca/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..22f1569a --- /dev/null +++ b/_static/locales/ca/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema del" + +msgid "Open an issue" +msgstr "Obriu un número" + +msgid "Download notebook file" +msgstr "Descarregar fitxer de quadern" + +msgid "Sphinx Book Theme" +msgstr "Tema del llibre Esfinx" + +msgid "Edit this page" +msgstr "Editeu aquesta pàgina" + +msgid "By" +msgstr "Per" + +msgid "Copyright" +msgstr "Copyright" + +msgid "Source repository" +msgstr "Dipòsit de fonts" + +msgid "previous page" +msgstr "Pàgina anterior" + +msgid "next page" +msgstr "pàgina següent" + +msgid "Toggle navigation" +msgstr "Commuta la navegació" + +msgid "suggest edit" +msgstr "suggerir edició" + +msgid "open issue" +msgstr "número obert" + +msgid "Launch" +msgstr "Llançament" + +msgid "Print to PDF" +msgstr "Imprimeix a PDF" + +msgid "By the" +msgstr "Per la" + +msgid "Last updated on" +msgstr "Darrera actualització el" + +msgid "Download source file" +msgstr "Baixeu el fitxer font" + +msgid "Download this page" +msgstr "Descarregueu aquesta pàgina" diff --git a/_static/locales/cs/LC_MESSAGES/booktheme.mo b/_static/locales/cs/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..c39e01a6 Binary files /dev/null and b/_static/locales/cs/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/cs/LC_MESSAGES/booktheme.po b/_static/locales/cs/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..afecd9e7 --- /dev/null +++ b/_static/locales/cs/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: cs\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Téma od" + +msgid "Open an issue" +msgstr "Otevřete problém" + +msgid "Contents" +msgstr "Obsah" + +msgid "Download notebook file" +msgstr "Stáhnout soubor poznámkového bloku" + +msgid "Sphinx Book Theme" +msgstr "Téma knihy Sfinga" + +msgid "Fullscreen mode" +msgstr "Režim celé obrazovky" + +msgid "Edit this page" +msgstr "Upravit tuto stránku" + +msgid "By" +msgstr "Podle" + +msgid "Copyright" +msgstr "autorská práva" + +msgid "Source repository" +msgstr "Zdrojové úložiště" + +msgid "previous page" +msgstr "předchozí stránka" + +msgid "next page" +msgstr "další strana" + +msgid "Toggle navigation" +msgstr "Přepnout navigaci" + +msgid "repository" +msgstr "úložiště" + +msgid "suggest edit" +msgstr "navrhnout úpravy" + +msgid "open issue" +msgstr "otevřené číslo" + +msgid "Launch" +msgstr "Zahájení" + +msgid "Print to PDF" +msgstr "Tisk do PDF" + +msgid "By the" +msgstr "Podle" + +msgid "Last updated on" +msgstr "Naposledy aktualizováno" + +msgid "Download source file" +msgstr "Stáhněte si zdrojový soubor" + +msgid "Download this page" +msgstr "Stáhněte si tuto stránku" diff --git a/_static/locales/da/LC_MESSAGES/booktheme.mo b/_static/locales/da/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..f43157d7 Binary files /dev/null and b/_static/locales/da/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/da/LC_MESSAGES/booktheme.po b/_static/locales/da/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..649c78a8 --- /dev/null +++ b/_static/locales/da/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: da\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema af" + +msgid "Open an issue" +msgstr "Åbn et problem" + +msgid "Contents" +msgstr "Indhold" + +msgid "Download notebook file" +msgstr "Download notesbog-fil" + +msgid "Sphinx Book Theme" +msgstr "Sphinx bogtema" + +msgid "Fullscreen mode" +msgstr "Fuldskærmstilstand" + +msgid "Edit this page" +msgstr "Rediger denne side" + +msgid "By" +msgstr "Ved" + +msgid "Copyright" +msgstr "ophavsret" + +msgid "Source repository" +msgstr "Kildelager" + +msgid "previous page" +msgstr "forrige side" + +msgid "next page" +msgstr "Næste side" + +msgid "Toggle navigation" +msgstr "Skift navigation" + +msgid "repository" +msgstr "lager" + +msgid "suggest edit" +msgstr "foreslå redigering" + +msgid "open issue" +msgstr "åbent nummer" + +msgid "Launch" +msgstr "Start" + +msgid "Print to PDF" +msgstr "Udskriv til PDF" + +msgid "By the" +msgstr "Ved" + +msgid "Last updated on" +msgstr "Sidst opdateret den" + +msgid "Download source file" +msgstr "Download kildefil" + +msgid "Download this page" +msgstr "Download denne side" diff --git a/_static/locales/de/LC_MESSAGES/booktheme.mo b/_static/locales/de/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..648b565c Binary files /dev/null and b/_static/locales/de/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/de/LC_MESSAGES/booktheme.po b/_static/locales/de/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..f51d2ecc --- /dev/null +++ b/_static/locales/de/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Thema von der" + +msgid "Open an issue" +msgstr "Öffnen Sie ein Problem" + +msgid "Contents" +msgstr "Inhalt" + +msgid "Download notebook file" +msgstr "Notebook-Datei herunterladen" + +msgid "Sphinx Book Theme" +msgstr "Sphinx-Buch-Thema" + +msgid "Fullscreen mode" +msgstr "Vollbildmodus" + +msgid "Edit this page" +msgstr "Bearbeite diese Seite" + +msgid "By" +msgstr "Durch" + +msgid "Copyright" +msgstr "Urheberrechte ©" + +msgid "Source repository" +msgstr "Quell-Repository" + +msgid "previous page" +msgstr "vorherige Seite" + +msgid "next page" +msgstr "Nächste Seite" + +msgid "Toggle navigation" +msgstr "Navigation umschalten" + +msgid "repository" +msgstr "Repository" + +msgid "suggest edit" +msgstr "vorschlagen zu bearbeiten" + +msgid "open issue" +msgstr "offenes Thema" + +msgid "Launch" +msgstr "Starten" + +msgid "Print to PDF" +msgstr "In PDF drucken" + +msgid "By the" +msgstr "Bis zum" + +msgid "Last updated on" +msgstr "Zuletzt aktualisiert am" + +msgid "Download source file" +msgstr "Quelldatei herunterladen" + +msgid "Download this page" +msgstr "Laden Sie diese Seite herunter" diff --git a/_static/locales/el/LC_MESSAGES/booktheme.mo b/_static/locales/el/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..fca6e935 Binary files /dev/null and b/_static/locales/el/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/el/LC_MESSAGES/booktheme.po b/_static/locales/el/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..8bec7905 --- /dev/null +++ b/_static/locales/el/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: el\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Θέμα από το" + +msgid "Open an issue" +msgstr "Ανοίξτε ένα ζήτημα" + +msgid "Contents" +msgstr "Περιεχόμενα" + +msgid "Download notebook file" +msgstr "Λήψη αρχείου σημειωματάριου" + +msgid "Sphinx Book Theme" +msgstr "Θέμα βιβλίου Sphinx" + +msgid "Fullscreen mode" +msgstr "ΛΕΙΤΟΥΡΓΙΑ ΠΛΗΡΟΥΣ ΟΘΟΝΗΣ" + +msgid "Edit this page" +msgstr "Επεξεργαστείτε αυτήν τη σελίδα" + +msgid "By" +msgstr "Με" + +msgid "Copyright" +msgstr "Πνευματική ιδιοκτησία" + +msgid "Source repository" +msgstr "Αποθήκη πηγής" + +msgid "previous page" +msgstr "προηγούμενη σελίδα" + +msgid "next page" +msgstr "επόμενη σελίδα" + +msgid "Toggle navigation" +msgstr "Εναλλαγή πλοήγησης" + +msgid "repository" +msgstr "αποθήκη" + +msgid "suggest edit" +msgstr "προτείνω επεξεργασία" + +msgid "open issue" +msgstr "ανοιχτό ζήτημα" + +msgid "Launch" +msgstr "Εκτόξευση" + +msgid "Print to PDF" +msgstr "Εκτύπωση σε PDF" + +msgid "By the" +msgstr "Από το" + +msgid "Last updated on" +msgstr "Τελευταία ενημέρωση στις" + +msgid "Download source file" +msgstr "Λήψη αρχείου προέλευσης" + +msgid "Download this page" +msgstr "Λήψη αυτής της σελίδας" diff --git a/_static/locales/eo/LC_MESSAGES/booktheme.mo b/_static/locales/eo/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..d1072bbe Binary files /dev/null and b/_static/locales/eo/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/eo/LC_MESSAGES/booktheme.po b/_static/locales/eo/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..d72a0481 --- /dev/null +++ b/_static/locales/eo/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: eo\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Temo de la" + +msgid "Open an issue" +msgstr "Malfermu numeron" + +msgid "Contents" +msgstr "Enhavo" + +msgid "Download notebook file" +msgstr "Elŝutu kajeran dosieron" + +msgid "Sphinx Book Theme" +msgstr "Sfinksa Libro-Temo" + +msgid "Fullscreen mode" +msgstr "Plenekrana reĝimo" + +msgid "Edit this page" +msgstr "Redaktu ĉi tiun paĝon" + +msgid "By" +msgstr "De" + +msgid "Copyright" +msgstr "Kopirajto" + +msgid "Source repository" +msgstr "Fonto-deponejo" + +msgid "previous page" +msgstr "antaŭa paĝo" + +msgid "next page" +msgstr "sekva paĝo" + +msgid "Toggle navigation" +msgstr "Ŝalti navigadon" + +msgid "repository" +msgstr "deponejo" + +msgid "suggest edit" +msgstr "sugesti redaktadon" + +msgid "open issue" +msgstr "malferma numero" + +msgid "Launch" +msgstr "Lanĉo" + +msgid "Print to PDF" +msgstr "Presi al PDF" + +msgid "By the" +msgstr "Per la" + +msgid "Last updated on" +msgstr "Laste ĝisdatigita la" + +msgid "Download source file" +msgstr "Elŝutu fontodosieron" + +msgid "Download this page" +msgstr "Elŝutu ĉi tiun paĝon" diff --git a/_static/locales/es/LC_MESSAGES/booktheme.mo b/_static/locales/es/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..ba2ee4dc Binary files /dev/null and b/_static/locales/es/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/es/LC_MESSAGES/booktheme.po b/_static/locales/es/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..611834b2 --- /dev/null +++ b/_static/locales/es/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema por el" + +msgid "Open an issue" +msgstr "Abrir un problema" + +msgid "Contents" +msgstr "Contenido" + +msgid "Download notebook file" +msgstr "Descargar archivo de cuaderno" + +msgid "Sphinx Book Theme" +msgstr "Tema del libro de la esfinge" + +msgid "Fullscreen mode" +msgstr "Modo de pantalla completa" + +msgid "Edit this page" +msgstr "Edita esta página" + +msgid "By" +msgstr "Por" + +msgid "Copyright" +msgstr "Derechos de autor" + +msgid "Source repository" +msgstr "Repositorio de origen" + +msgid "previous page" +msgstr "pagina anterior" + +msgid "next page" +msgstr "siguiente página" + +msgid "Toggle navigation" +msgstr "Navegación de palanca" + +msgid "repository" +msgstr "repositorio" + +msgid "suggest edit" +msgstr "sugerir editar" + +msgid "open issue" +msgstr "Tema abierto" + +msgid "Launch" +msgstr "Lanzamiento" + +msgid "Print to PDF" +msgstr "Imprimir en PDF" + +msgid "By the" +msgstr "Por el" + +msgid "Last updated on" +msgstr "Ultima actualización en" + +msgid "Download source file" +msgstr "Descargar archivo fuente" + +msgid "Download this page" +msgstr "Descarga esta pagina" diff --git a/_static/locales/et/LC_MESSAGES/booktheme.mo b/_static/locales/et/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..983b8239 Binary files /dev/null and b/_static/locales/et/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/et/LC_MESSAGES/booktheme.po b/_static/locales/et/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..345088f0 --- /dev/null +++ b/_static/locales/et/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: et\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Teema" + +msgid "Open an issue" +msgstr "Avage probleem" + +msgid "Contents" +msgstr "Sisu" + +msgid "Download notebook file" +msgstr "Laadige sülearvuti fail alla" + +msgid "Sphinx Book Theme" +msgstr "Sfinksiraamatu teema" + +msgid "Fullscreen mode" +msgstr "Täisekraanirežiim" + +msgid "Edit this page" +msgstr "Muutke seda lehte" + +msgid "By" +msgstr "Kõrval" + +msgid "Copyright" +msgstr "Autoriõigus" + +msgid "Source repository" +msgstr "Allikahoidla" + +msgid "previous page" +msgstr "eelmine leht" + +msgid "next page" +msgstr "järgmine leht" + +msgid "Toggle navigation" +msgstr "Lülita navigeerimine sisse" + +msgid "repository" +msgstr "hoidla" + +msgid "suggest edit" +msgstr "soovita muuta" + +msgid "open issue" +msgstr "avatud küsimus" + +msgid "Launch" +msgstr "Käivitage" + +msgid "Print to PDF" +msgstr "Prindi PDF-i" + +msgid "By the" +msgstr "Autor" + +msgid "Last updated on" +msgstr "Viimati uuendatud" + +msgid "Download source file" +msgstr "Laadige alla lähtefail" + +msgid "Download this page" +msgstr "Laadige see leht alla" diff --git a/_static/locales/fi/LC_MESSAGES/booktheme.mo b/_static/locales/fi/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..d8ac0545 Binary files /dev/null and b/_static/locales/fi/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/fi/LC_MESSAGES/booktheme.po b/_static/locales/fi/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..d97a08dc --- /dev/null +++ b/_static/locales/fi/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Teeman tekijä" + +msgid "Open an issue" +msgstr "Avaa ongelma" + +msgid "Contents" +msgstr "Sisällys" + +msgid "Download notebook file" +msgstr "Lataa muistikirjatiedosto" + +msgid "Sphinx Book Theme" +msgstr "Sphinx-kirjan teema" + +msgid "Fullscreen mode" +msgstr "Koko näytön tila" + +msgid "Edit this page" +msgstr "Muokkaa tätä sivua" + +msgid "By" +msgstr "Tekijä" + +msgid "Copyright" +msgstr "Tekijänoikeus" + +msgid "Source repository" +msgstr "Lähteen arkisto" + +msgid "previous page" +msgstr "Edellinen sivu" + +msgid "next page" +msgstr "seuraava sivu" + +msgid "Toggle navigation" +msgstr "Vaihda navigointia" + +msgid "repository" +msgstr "arkisto" + +msgid "suggest edit" +msgstr "ehdottaa muokkausta" + +msgid "open issue" +msgstr "avoin ongelma" + +msgid "Launch" +msgstr "Tuoda markkinoille" + +msgid "Print to PDF" +msgstr "Tulosta PDF-tiedostoon" + +msgid "By the" +msgstr "Mukaan" + +msgid "Last updated on" +msgstr "Viimeksi päivitetty" + +msgid "Download source file" +msgstr "Lataa lähdetiedosto" + +msgid "Download this page" +msgstr "Lataa tämä sivu" diff --git a/_static/locales/fr/LC_MESSAGES/booktheme.mo b/_static/locales/fr/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..f663d39f Binary files /dev/null and b/_static/locales/fr/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/fr/LC_MESSAGES/booktheme.po b/_static/locales/fr/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..88f35173 --- /dev/null +++ b/_static/locales/fr/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Thème par le" + +msgid "Open an issue" +msgstr "Ouvrez un problème" + +msgid "Contents" +msgstr "Contenu" + +msgid "Download notebook file" +msgstr "Télécharger le fichier notebook" + +msgid "Sphinx Book Theme" +msgstr "Thème du livre Sphinx" + +msgid "Fullscreen mode" +msgstr "Mode plein écran" + +msgid "Edit this page" +msgstr "Modifier cette page" + +msgid "By" +msgstr "Par" + +msgid "Copyright" +msgstr "droits d'auteur" + +msgid "Source repository" +msgstr "Dépôt source" + +msgid "previous page" +msgstr "page précédente" + +msgid "next page" +msgstr "page suivante" + +msgid "Toggle navigation" +msgstr "Basculer la navigation" + +msgid "repository" +msgstr "dépôt" + +msgid "suggest edit" +msgstr "suggestion de modification" + +msgid "open issue" +msgstr "signaler un problème" + +msgid "Launch" +msgstr "lancement" + +msgid "Print to PDF" +msgstr "Imprimer au format PDF" + +msgid "By the" +msgstr "Par le" + +msgid "Last updated on" +msgstr "Dernière mise à jour le" + +msgid "Download source file" +msgstr "Télécharger le fichier source" + +msgid "Download this page" +msgstr "Téléchargez cette page" diff --git a/_static/locales/hr/LC_MESSAGES/booktheme.mo b/_static/locales/hr/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..eca4a1a2 Binary files /dev/null and b/_static/locales/hr/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/hr/LC_MESSAGES/booktheme.po b/_static/locales/hr/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..fb9440ac --- /dev/null +++ b/_static/locales/hr/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hr\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema autora" + +msgid "Open an issue" +msgstr "Otvorite izdanje" + +msgid "Contents" +msgstr "Sadržaj" + +msgid "Download notebook file" +msgstr "Preuzmi datoteku bilježnice" + +msgid "Sphinx Book Theme" +msgstr "Tema knjige Sphinx" + +msgid "Fullscreen mode" +msgstr "Način preko cijelog zaslona" + +msgid "Edit this page" +msgstr "Uredite ovu stranicu" + +msgid "By" +msgstr "Po" + +msgid "Copyright" +msgstr "Autorska prava" + +msgid "Source repository" +msgstr "Izvorno spremište" + +msgid "previous page" +msgstr "Prethodna stranica" + +msgid "next page" +msgstr "sljedeća stranica" + +msgid "Toggle navigation" +msgstr "Uključi / isključi navigaciju" + +msgid "repository" +msgstr "spremište" + +msgid "suggest edit" +msgstr "predloži uređivanje" + +msgid "open issue" +msgstr "otvoreno izdanje" + +msgid "Launch" +msgstr "Pokrenite" + +msgid "Print to PDF" +msgstr "Ispis u PDF" + +msgid "By the" +msgstr "Od strane" + +msgid "Last updated on" +msgstr "Posljednje ažuriranje:" + +msgid "Download source file" +msgstr "Preuzmi izvornu datoteku" + +msgid "Download this page" +msgstr "Preuzmite ovu stranicu" diff --git a/_static/locales/id/LC_MESSAGES/booktheme.mo b/_static/locales/id/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..d07a06a9 Binary files /dev/null and b/_static/locales/id/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/id/LC_MESSAGES/booktheme.po b/_static/locales/id/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..9ffb56f7 --- /dev/null +++ b/_static/locales/id/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: id\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema oleh" + +msgid "Open an issue" +msgstr "Buka masalah" + +msgid "Contents" +msgstr "Isi" + +msgid "Download notebook file" +msgstr "Unduh file notebook" + +msgid "Sphinx Book Theme" +msgstr "Tema Buku Sphinx" + +msgid "Fullscreen mode" +msgstr "Mode layar penuh" + +msgid "Edit this page" +msgstr "Edit halaman ini" + +msgid "By" +msgstr "Oleh" + +msgid "Copyright" +msgstr "hak cipta" + +msgid "Source repository" +msgstr "Repositori sumber" + +msgid "previous page" +msgstr "halaman sebelumnya" + +msgid "next page" +msgstr "halaman selanjutnya" + +msgid "Toggle navigation" +msgstr "Alihkan navigasi" + +msgid "repository" +msgstr "gudang" + +msgid "suggest edit" +msgstr "menyarankan edit" + +msgid "open issue" +msgstr "masalah terbuka" + +msgid "Launch" +msgstr "Meluncurkan" + +msgid "Print to PDF" +msgstr "Cetak ke PDF" + +msgid "By the" +msgstr "Oleh" + +msgid "Last updated on" +msgstr "Terakhir diperbarui saat" + +msgid "Download source file" +msgstr "Unduh file sumber" + +msgid "Download this page" +msgstr "Unduh halaman ini" diff --git a/_static/locales/it/LC_MESSAGES/booktheme.mo b/_static/locales/it/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..53ba476e Binary files /dev/null and b/_static/locales/it/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/it/LC_MESSAGES/booktheme.po b/_static/locales/it/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..04308dd2 --- /dev/null +++ b/_static/locales/it/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema di" + +msgid "Open an issue" +msgstr "Apri un problema" + +msgid "Contents" +msgstr "Contenuti" + +msgid "Download notebook file" +msgstr "Scarica il file del taccuino" + +msgid "Sphinx Book Theme" +msgstr "Tema del libro della Sfinge" + +msgid "Fullscreen mode" +msgstr "Modalità schermo intero" + +msgid "Edit this page" +msgstr "Modifica questa pagina" + +msgid "By" +msgstr "Di" + +msgid "Copyright" +msgstr "Diritto d'autore" + +msgid "Source repository" +msgstr "Repository di origine" + +msgid "previous page" +msgstr "pagina precedente" + +msgid "next page" +msgstr "pagina successiva" + +msgid "Toggle navigation" +msgstr "Attiva / disattiva la navigazione" + +msgid "repository" +msgstr "repository" + +msgid "suggest edit" +msgstr "suggerisci modifica" + +msgid "open issue" +msgstr "questione aperta" + +msgid "Launch" +msgstr "Lanciare" + +msgid "Print to PDF" +msgstr "Stampa in PDF" + +msgid "By the" +msgstr "Dal" + +msgid "Last updated on" +msgstr "Ultimo aggiornamento il" + +msgid "Download source file" +msgstr "Scarica il file sorgente" + +msgid "Download this page" +msgstr "Scarica questa pagina" diff --git a/_static/locales/iw/LC_MESSAGES/booktheme.mo b/_static/locales/iw/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..a45c6575 Binary files /dev/null and b/_static/locales/iw/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/iw/LC_MESSAGES/booktheme.po b/_static/locales/iw/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..4ea190d3 --- /dev/null +++ b/_static/locales/iw/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: iw\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "נושא מאת" + +msgid "Open an issue" +msgstr "פתח גיליון" + +msgid "Contents" +msgstr "תוכן" + +msgid "Download notebook file" +msgstr "הורד קובץ מחברת" + +msgid "Sphinx Book Theme" +msgstr "נושא ספר ספינקס" + +msgid "Fullscreen mode" +msgstr "מצב מסך מלא" + +msgid "Edit this page" +msgstr "ערוך דף זה" + +msgid "By" +msgstr "על ידי" + +msgid "Copyright" +msgstr "זכויות יוצרים" + +msgid "Source repository" +msgstr "מאגר המקורות" + +msgid "previous page" +msgstr "עמוד קודם" + +msgid "next page" +msgstr "עמוד הבא" + +msgid "Toggle navigation" +msgstr "החלף ניווט" + +msgid "repository" +msgstr "מאגר" + +msgid "suggest edit" +msgstr "מציע לערוך" + +msgid "open issue" +msgstr "בעיה פתוחה" + +msgid "Launch" +msgstr "לְהַשִׁיק" + +msgid "Print to PDF" +msgstr "הדפס לקובץ PDF" + +msgid "By the" +msgstr "דרך" + +msgid "Last updated on" +msgstr "עודכן לאחרונה ב" + +msgid "Download source file" +msgstr "הורד את קובץ המקור" + +msgid "Download this page" +msgstr "הורד דף זה" diff --git a/_static/locales/ja/LC_MESSAGES/booktheme.mo b/_static/locales/ja/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..1cefd29c Binary files /dev/null and b/_static/locales/ja/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ja/LC_MESSAGES/booktheme.po b/_static/locales/ja/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..77d5a097 --- /dev/null +++ b/_static/locales/ja/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "のテーマ" + +msgid "Open an issue" +msgstr "問題を報告" + +msgid "Contents" +msgstr "目次" + +msgid "Download notebook file" +msgstr "ノートブックファイルをダウンロード" + +msgid "Sphinx Book Theme" +msgstr "スフィンクスの本のテーマ" + +msgid "Fullscreen mode" +msgstr "全画面モード" + +msgid "Edit this page" +msgstr "このページを編集" + +msgid "By" +msgstr "著者" + +msgid "Copyright" +msgstr "Copyright" + +msgid "Source repository" +msgstr "ソースリポジトリ" + +msgid "previous page" +msgstr "前のページ" + +msgid "next page" +msgstr "次のページ" + +msgid "Toggle navigation" +msgstr "ナビゲーションを切り替え" + +msgid "repository" +msgstr "リポジトリ" + +msgid "suggest edit" +msgstr "編集を提案する" + +msgid "open issue" +msgstr "未解決の問題" + +msgid "Launch" +msgstr "起動" + +msgid "Print to PDF" +msgstr "PDFに印刷" + +msgid "By the" +msgstr "によって" + +msgid "Last updated on" +msgstr "最終更新日" + +msgid "Download source file" +msgstr "ソースファイルをダウンロード" + +msgid "Download this page" +msgstr "このページをダウンロード" diff --git a/_static/locales/ko/LC_MESSAGES/booktheme.mo b/_static/locales/ko/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..06c7ec93 Binary files /dev/null and b/_static/locales/ko/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ko/LC_MESSAGES/booktheme.po b/_static/locales/ko/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..6ee3d781 --- /dev/null +++ b/_static/locales/ko/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ko\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "테마별" + +msgid "Open an issue" +msgstr "이슈 열기" + +msgid "Contents" +msgstr "내용" + +msgid "Download notebook file" +msgstr "노트북 파일 다운로드" + +msgid "Sphinx Book Theme" +msgstr "스핑크스 도서 테마" + +msgid "Fullscreen mode" +msgstr "전체 화면으로보기" + +msgid "Edit this page" +msgstr "이 페이지 편집" + +msgid "By" +msgstr "으로" + +msgid "Copyright" +msgstr "저작권" + +msgid "Source repository" +msgstr "소스 저장소" + +msgid "previous page" +msgstr "이전 페이지" + +msgid "next page" +msgstr "다음 페이지" + +msgid "Toggle navigation" +msgstr "탐색 전환" + +msgid "repository" +msgstr "저장소" + +msgid "suggest edit" +msgstr "편집 제안" + +msgid "open issue" +msgstr "열린 문제" + +msgid "Launch" +msgstr "시작하다" + +msgid "Print to PDF" +msgstr "PDF로 인쇄" + +msgid "By the" +msgstr "에 의해" + +msgid "Last updated on" +msgstr "마지막 업데이트" + +msgid "Download source file" +msgstr "소스 파일 다운로드" + +msgid "Download this page" +msgstr "이 페이지 다운로드" diff --git a/_static/locales/lt/LC_MESSAGES/booktheme.mo b/_static/locales/lt/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..4468ba04 Binary files /dev/null and b/_static/locales/lt/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/lt/LC_MESSAGES/booktheme.po b/_static/locales/lt/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..01be2679 --- /dev/null +++ b/_static/locales/lt/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lt\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema" + +msgid "Open an issue" +msgstr "Atidarykite problemą" + +msgid "Contents" +msgstr "Turinys" + +msgid "Download notebook file" +msgstr "Atsisiųsti nešiojamojo kompiuterio failą" + +msgid "Sphinx Book Theme" +msgstr "Sfinkso knygos tema" + +msgid "Fullscreen mode" +msgstr "Pilno ekrano režimas" + +msgid "Edit this page" +msgstr "Redaguoti šį puslapį" + +msgid "By" +msgstr "Iki" + +msgid "Copyright" +msgstr "Autorių teisės" + +msgid "Source repository" +msgstr "Šaltinio saugykla" + +msgid "previous page" +msgstr "Ankstesnis puslapis" + +msgid "next page" +msgstr "Kitas puslapis" + +msgid "Toggle navigation" +msgstr "Perjungti naršymą" + +msgid "repository" +msgstr "saugykla" + +msgid "suggest edit" +msgstr "pasiūlyti redaguoti" + +msgid "open issue" +msgstr "atviras klausimas" + +msgid "Launch" +msgstr "Paleiskite" + +msgid "Print to PDF" +msgstr "Spausdinti į PDF" + +msgid "By the" +msgstr "Prie" + +msgid "Last updated on" +msgstr "Paskutinį kartą atnaujinta" + +msgid "Download source file" +msgstr "Atsisiųsti šaltinio failą" + +msgid "Download this page" +msgstr "Atsisiųskite šį puslapį" diff --git a/_static/locales/lv/LC_MESSAGES/booktheme.mo b/_static/locales/lv/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..74aa4d89 Binary files /dev/null and b/_static/locales/lv/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/lv/LC_MESSAGES/booktheme.po b/_static/locales/lv/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..993a1e41 --- /dev/null +++ b/_static/locales/lv/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lv\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Autora tēma" + +msgid "Open an issue" +msgstr "Atveriet problēmu" + +msgid "Contents" +msgstr "Saturs" + +msgid "Download notebook file" +msgstr "Lejupielādēt piezīmju grāmatiņu" + +msgid "Sphinx Book Theme" +msgstr "Sfinksa grāmatas tēma" + +msgid "Fullscreen mode" +msgstr "Pilnekrāna režīms" + +msgid "Edit this page" +msgstr "Rediģēt šo lapu" + +msgid "By" +msgstr "Autors" + +msgid "Copyright" +msgstr "Autortiesības" + +msgid "Source repository" +msgstr "Avota krātuve" + +msgid "previous page" +msgstr "iepriekšējā lapa" + +msgid "next page" +msgstr "nākamā lapaspuse" + +msgid "Toggle navigation" +msgstr "Pārslēgt navigāciju" + +msgid "repository" +msgstr "krātuve" + +msgid "suggest edit" +msgstr "ieteikt rediģēt" + +msgid "open issue" +msgstr "atklāts jautājums" + +msgid "Launch" +msgstr "Uzsākt" + +msgid "Print to PDF" +msgstr "Drukāt PDF formātā" + +msgid "By the" +msgstr "Ar" + +msgid "Last updated on" +msgstr "Pēdējoreiz atjaunināts" + +msgid "Download source file" +msgstr "Lejupielādēt avota failu" + +msgid "Download this page" +msgstr "Lejupielādējiet šo lapu" diff --git a/_static/locales/ml/LC_MESSAGES/booktheme.mo b/_static/locales/ml/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..2736e8fc Binary files /dev/null and b/_static/locales/ml/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ml/LC_MESSAGES/booktheme.po b/_static/locales/ml/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..81daf7c8 --- /dev/null +++ b/_static/locales/ml/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ml\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "പ്രമേയം" + +msgid "Open an issue" +msgstr "ഒരു പ്രശ്നം തുറക്കുക" + +msgid "Download notebook file" +msgstr "നോട്ട്ബുക്ക് ഫയൽ ഡൺലോഡ് ചെയ്യുക" + +msgid "Sphinx Book Theme" +msgstr "സ്ഫിങ്ക്സ് പുസ്തക തീം" + +msgid "Edit this page" +msgstr "ഈ പേജ് എഡിറ്റുചെയ്യുക" + +msgid "By" +msgstr "എഴുതിയത്" + +msgid "Copyright" +msgstr "പകർപ്പവകാശം" + +msgid "Source repository" +msgstr "ഉറവിട ശേഖരം" + +msgid "previous page" +msgstr "മുൻപത്തെ താൾ" + +msgid "next page" +msgstr "അടുത്ത പേജ്" + +msgid "Toggle navigation" +msgstr "നാവിഗേഷൻ ടോഗിൾ ചെയ്യുക" + +msgid "suggest edit" +msgstr "എഡിറ്റുചെയ്യാൻ നിർദ്ദേശിക്കുക" + +msgid "open issue" +msgstr "തുറന്ന പ്രശ്നം" + +msgid "Launch" +msgstr "സമാരംഭിക്കുക" + +msgid "Print to PDF" +msgstr "PDF- ലേക്ക് പ്രിന്റുചെയ്യുക" + +msgid "By the" +msgstr "എഴുതിയത്" + +msgid "Last updated on" +msgstr "അവസാനം അപ്‌ഡേറ്റുചെയ്‌തത്" + +msgid "Download source file" +msgstr "ഉറവിട ഫയൽ ഡൗൺലോഡുചെയ്യുക" + +msgid "Download this page" +msgstr "ഈ പേജ് ഡൗൺലോഡുചെയ്യുക" diff --git a/_static/locales/mr/LC_MESSAGES/booktheme.mo b/_static/locales/mr/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..fe530100 Binary files /dev/null and b/_static/locales/mr/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/mr/LC_MESSAGES/booktheme.po b/_static/locales/mr/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..fd857bff --- /dev/null +++ b/_static/locales/mr/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: mr\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "द्वारा थीम" + +msgid "Open an issue" +msgstr "एक मुद्दा उघडा" + +msgid "Download notebook file" +msgstr "नोटबुक फाईल डाउनलोड करा" + +msgid "Sphinx Book Theme" +msgstr "स्फिंक्स बुक थीम" + +msgid "Edit this page" +msgstr "हे पृष्ठ संपादित करा" + +msgid "By" +msgstr "द्वारा" + +msgid "Copyright" +msgstr "कॉपीराइट" + +msgid "Source repository" +msgstr "स्त्रोत भांडार" + +msgid "previous page" +msgstr "मागील पान" + +msgid "next page" +msgstr "पुढील पृष्ठ" + +msgid "Toggle navigation" +msgstr "नेव्हिगेशन टॉगल करा" + +msgid "suggest edit" +msgstr "संपादन सुचवा" + +msgid "open issue" +msgstr "खुला मुद्दा" + +msgid "Launch" +msgstr "लाँच करा" + +msgid "Print to PDF" +msgstr "पीडीएफवर मुद्रित करा" + +msgid "By the" +msgstr "द्वारा" + +msgid "Last updated on" +msgstr "अखेरचे अद्यतनित" + +msgid "Download source file" +msgstr "स्त्रोत फाइल डाउनलोड करा" + +msgid "Download this page" +msgstr "हे पृष्ठ डाउनलोड करा" diff --git a/_static/locales/ms/LC_MESSAGES/booktheme.mo b/_static/locales/ms/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..f02603fa Binary files /dev/null and b/_static/locales/ms/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ms/LC_MESSAGES/booktheme.po b/_static/locales/ms/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..b616d70f --- /dev/null +++ b/_static/locales/ms/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ms\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema oleh" + +msgid "Open an issue" +msgstr "Buka masalah" + +msgid "Download notebook file" +msgstr "Muat turun fail buku nota" + +msgid "Sphinx Book Theme" +msgstr "Tema Buku Sphinx" + +msgid "Edit this page" +msgstr "Edit halaman ini" + +msgid "By" +msgstr "Oleh" + +msgid "Copyright" +msgstr "hak cipta" + +msgid "Source repository" +msgstr "Repositori sumber" + +msgid "previous page" +msgstr "halaman sebelumnya" + +msgid "next page" +msgstr "muka surat seterusnya" + +msgid "Toggle navigation" +msgstr "Togol navigasi" + +msgid "suggest edit" +msgstr "cadangkan edit" + +msgid "open issue" +msgstr "isu terbuka" + +msgid "Launch" +msgstr "Lancarkan" + +msgid "Print to PDF" +msgstr "Cetak ke PDF" + +msgid "By the" +msgstr "Oleh" + +msgid "Last updated on" +msgstr "Terakhir dikemas kini pada" + +msgid "Download source file" +msgstr "Muat turun fail sumber" + +msgid "Download this page" +msgstr "Muat turun halaman ini" diff --git a/_static/locales/nl/LC_MESSAGES/booktheme.mo b/_static/locales/nl/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..e59e7ecb Binary files /dev/null and b/_static/locales/nl/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/nl/LC_MESSAGES/booktheme.po b/_static/locales/nl/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..f16f4bcc --- /dev/null +++ b/_static/locales/nl/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Thema door de" + +msgid "Open an issue" +msgstr "Open een probleem" + +msgid "Contents" +msgstr "Inhoud" + +msgid "Download notebook file" +msgstr "Download notebookbestand" + +msgid "Sphinx Book Theme" +msgstr "Sphinx-boekthema" + +msgid "Fullscreen mode" +msgstr "Volledig scherm" + +msgid "Edit this page" +msgstr "bewerk deze pagina" + +msgid "By" +msgstr "Door" + +msgid "Copyright" +msgstr "auteursrechten" + +msgid "Source repository" +msgstr "Bronopslagplaats" + +msgid "previous page" +msgstr "vorige pagina" + +msgid "next page" +msgstr "volgende bladzijde" + +msgid "Toggle navigation" +msgstr "Schakel navigatie" + +msgid "repository" +msgstr "repository" + +msgid "suggest edit" +msgstr "suggereren bewerken" + +msgid "open issue" +msgstr "open probleem" + +msgid "Launch" +msgstr "Lancering" + +msgid "Print to PDF" +msgstr "Afdrukken naar pdf" + +msgid "By the" +msgstr "Door de" + +msgid "Last updated on" +msgstr "Laatst geupdate op" + +msgid "Download source file" +msgstr "Download het bronbestand" + +msgid "Download this page" +msgstr "Download deze pagina" diff --git a/_static/locales/no/LC_MESSAGES/booktheme.mo b/_static/locales/no/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..6cd15c88 Binary files /dev/null and b/_static/locales/no/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/no/LC_MESSAGES/booktheme.po b/_static/locales/no/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..b1d304ee --- /dev/null +++ b/_static/locales/no/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: no\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema av" + +msgid "Open an issue" +msgstr "Åpne et problem" + +msgid "Contents" +msgstr "Innhold" + +msgid "Download notebook file" +msgstr "Last ned notatbokfilen" + +msgid "Sphinx Book Theme" +msgstr "Sphinx boktema" + +msgid "Fullscreen mode" +msgstr "Fullskjerm-modus" + +msgid "Edit this page" +msgstr "Rediger denne siden" + +msgid "By" +msgstr "Av" + +msgid "Copyright" +msgstr "opphavsrett" + +msgid "Source repository" +msgstr "Kildedepot" + +msgid "previous page" +msgstr "forrige side" + +msgid "next page" +msgstr "neste side" + +msgid "Toggle navigation" +msgstr "Bytt navigasjon" + +msgid "repository" +msgstr "oppbevaringssted" + +msgid "suggest edit" +msgstr "foreslå redigering" + +msgid "open issue" +msgstr "åpent nummer" + +msgid "Launch" +msgstr "Start" + +msgid "Print to PDF" +msgstr "Skriv ut til PDF" + +msgid "By the" +msgstr "Ved" + +msgid "Last updated on" +msgstr "Sist oppdatert den" + +msgid "Download source file" +msgstr "Last ned kildefilen" + +msgid "Download this page" +msgstr "Last ned denne siden" diff --git a/_static/locales/pl/LC_MESSAGES/booktheme.mo b/_static/locales/pl/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..9ebb584f Binary files /dev/null and b/_static/locales/pl/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/pl/LC_MESSAGES/booktheme.po b/_static/locales/pl/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..80d2c896 --- /dev/null +++ b/_static/locales/pl/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Motyw autorstwa" + +msgid "Open an issue" +msgstr "Otwórz problem" + +msgid "Contents" +msgstr "Zawartość" + +msgid "Download notebook file" +msgstr "Pobierz plik notatnika" + +msgid "Sphinx Book Theme" +msgstr "Motyw książki Sphinx" + +msgid "Fullscreen mode" +msgstr "Pełny ekran" + +msgid "Edit this page" +msgstr "Edytuj tę strone" + +msgid "By" +msgstr "Przez" + +msgid "Copyright" +msgstr "prawa autorskie" + +msgid "Source repository" +msgstr "Repozytorium źródłowe" + +msgid "previous page" +msgstr "Poprzednia strona" + +msgid "next page" +msgstr "Następna strona" + +msgid "Toggle navigation" +msgstr "Przełącz nawigację" + +msgid "repository" +msgstr "magazyn" + +msgid "suggest edit" +msgstr "zaproponuj edycję" + +msgid "open issue" +msgstr "otwarty problem" + +msgid "Launch" +msgstr "Uruchomić" + +msgid "Print to PDF" +msgstr "Drukuj do PDF" + +msgid "By the" +msgstr "Przez" + +msgid "Last updated on" +msgstr "Ostatnia aktualizacja" + +msgid "Download source file" +msgstr "Pobierz plik źródłowy" + +msgid "Download this page" +msgstr "Pobierz tę stronę" diff --git a/_static/locales/pt/LC_MESSAGES/booktheme.mo b/_static/locales/pt/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..d0ddb872 Binary files /dev/null and b/_static/locales/pt/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/pt/LC_MESSAGES/booktheme.po b/_static/locales/pt/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..45ac847f --- /dev/null +++ b/_static/locales/pt/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema por" + +msgid "Open an issue" +msgstr "Abra um problema" + +msgid "Contents" +msgstr "Conteúdo" + +msgid "Download notebook file" +msgstr "Baixar arquivo de notebook" + +msgid "Sphinx Book Theme" +msgstr "Tema do livro Sphinx" + +msgid "Fullscreen mode" +msgstr "Modo tela cheia" + +msgid "Edit this page" +msgstr "Edite essa página" + +msgid "By" +msgstr "De" + +msgid "Copyright" +msgstr "direito autoral" + +msgid "Source repository" +msgstr "Repositório fonte" + +msgid "previous page" +msgstr "página anterior" + +msgid "next page" +msgstr "próxima página" + +msgid "Toggle navigation" +msgstr "Alternar de navegação" + +msgid "repository" +msgstr "repositório" + +msgid "suggest edit" +msgstr "sugerir edição" + +msgid "open issue" +msgstr "questão aberta" + +msgid "Launch" +msgstr "Lançamento" + +msgid "Print to PDF" +msgstr "Imprimir em PDF" + +msgid "By the" +msgstr "Pelo" + +msgid "Last updated on" +msgstr "Última atualização em" + +msgid "Download source file" +msgstr "Baixar arquivo fonte" + +msgid "Download this page" +msgstr "Baixe esta página" diff --git a/_static/locales/ro/LC_MESSAGES/booktheme.mo b/_static/locales/ro/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..3c36ab1d Binary files /dev/null and b/_static/locales/ro/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ro/LC_MESSAGES/booktheme.po b/_static/locales/ro/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..532b3b84 --- /dev/null +++ b/_static/locales/ro/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ro\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema de" + +msgid "Open an issue" +msgstr "Deschideți o problemă" + +msgid "Contents" +msgstr "Cuprins" + +msgid "Download notebook file" +msgstr "Descărcați fișierul notebook" + +msgid "Sphinx Book Theme" +msgstr "Tema Sphinx Book" + +msgid "Fullscreen mode" +msgstr "Modul ecran întreg" + +msgid "Edit this page" +msgstr "Editați această pagină" + +msgid "By" +msgstr "De" + +msgid "Copyright" +msgstr "Drepturi de autor" + +msgid "Source repository" +msgstr "Depozit sursă" + +msgid "previous page" +msgstr "pagina anterioară" + +msgid "next page" +msgstr "pagina următoare" + +msgid "Toggle navigation" +msgstr "Comutare navigare" + +msgid "repository" +msgstr "repertoriu" + +msgid "suggest edit" +msgstr "sugerează editare" + +msgid "open issue" +msgstr "problema deschisă" + +msgid "Launch" +msgstr "Lansa" + +msgid "Print to PDF" +msgstr "Imprimați în PDF" + +msgid "By the" +msgstr "Langa" + +msgid "Last updated on" +msgstr "Ultima actualizare la" + +msgid "Download source file" +msgstr "Descărcați fișierul sursă" + +msgid "Download this page" +msgstr "Descarcă această pagină" diff --git a/_static/locales/ru/LC_MESSAGES/booktheme.mo b/_static/locales/ru/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..6b8ca41f Binary files /dev/null and b/_static/locales/ru/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ru/LC_MESSAGES/booktheme.po b/_static/locales/ru/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..b718b482 --- /dev/null +++ b/_static/locales/ru/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ru\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Тема от" + +msgid "Open an issue" +msgstr "Открыть вопрос" + +msgid "Contents" +msgstr "Содержание" + +msgid "Download notebook file" +msgstr "Скачать файл записной книжки" + +msgid "Sphinx Book Theme" +msgstr "Тема книги Сфинкс" + +msgid "Fullscreen mode" +msgstr "Полноэкранный режим" + +msgid "Edit this page" +msgstr "Редактировать эту страницу" + +msgid "By" +msgstr "По" + +msgid "Copyright" +msgstr "авторское право" + +msgid "Source repository" +msgstr "Исходный репозиторий" + +msgid "previous page" +msgstr "Предыдущая страница" + +msgid "next page" +msgstr "Следующая страница" + +msgid "Toggle navigation" +msgstr "Переключить навигацию" + +msgid "repository" +msgstr "хранилище" + +msgid "suggest edit" +msgstr "предложить редактировать" + +msgid "open issue" +msgstr "открытый вопрос" + +msgid "Launch" +msgstr "Запуск" + +msgid "Print to PDF" +msgstr "Распечатать в PDF" + +msgid "By the" +msgstr "Посредством" + +msgid "Last updated on" +msgstr "Последнее обновление" + +msgid "Download source file" +msgstr "Скачать исходный файл" + +msgid "Download this page" +msgstr "Загрузите эту страницу" diff --git a/_static/locales/sk/LC_MESSAGES/booktheme.mo b/_static/locales/sk/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..59bd0ddf Binary files /dev/null and b/_static/locales/sk/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/sk/LC_MESSAGES/booktheme.po b/_static/locales/sk/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..f6c423b6 --- /dev/null +++ b/_static/locales/sk/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sk\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Téma od" + +msgid "Open an issue" +msgstr "Otvorte problém" + +msgid "Contents" +msgstr "Obsah" + +msgid "Download notebook file" +msgstr "Stiahnite si zošit" + +msgid "Sphinx Book Theme" +msgstr "Téma knihy Sfinga" + +msgid "Fullscreen mode" +msgstr "Režim celej obrazovky" + +msgid "Edit this page" +msgstr "Upraviť túto stránku" + +msgid "By" +msgstr "Autor:" + +msgid "Copyright" +msgstr "Autorské práva" + +msgid "Source repository" +msgstr "Zdrojové úložisko" + +msgid "previous page" +msgstr "predchádzajúca strana" + +msgid "next page" +msgstr "ďalšia strana" + +msgid "Toggle navigation" +msgstr "Prepnúť navigáciu" + +msgid "repository" +msgstr "Úložisko" + +msgid "suggest edit" +msgstr "navrhnúť úpravu" + +msgid "open issue" +msgstr "otvorené vydanie" + +msgid "Launch" +msgstr "Spustiť" + +msgid "Print to PDF" +msgstr "Tlač do PDF" + +msgid "By the" +msgstr "Podľa" + +msgid "Last updated on" +msgstr "Posledná aktualizácia dňa" + +msgid "Download source file" +msgstr "Stiahnite si zdrojový súbor" + +msgid "Download this page" +msgstr "Stiahnite si túto stránku" diff --git a/_static/locales/sl/LC_MESSAGES/booktheme.mo b/_static/locales/sl/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..87bf26de Binary files /dev/null and b/_static/locales/sl/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/sl/LC_MESSAGES/booktheme.po b/_static/locales/sl/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..9822dc58 --- /dev/null +++ b/_static/locales/sl/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema avtorja" + +msgid "Open an issue" +msgstr "Odprite številko" + +msgid "Contents" +msgstr "Vsebina" + +msgid "Download notebook file" +msgstr "Prenesite datoteko zvezka" + +msgid "Sphinx Book Theme" +msgstr "Tema knjige Sphinx" + +msgid "Fullscreen mode" +msgstr "Celozaslonski način" + +msgid "Edit this page" +msgstr "Uredite to stran" + +msgid "By" +msgstr "Avtor" + +msgid "Copyright" +msgstr "avtorske pravice" + +msgid "Source repository" +msgstr "Izvorno skladišče" + +msgid "previous page" +msgstr "Prejšnja stran" + +msgid "next page" +msgstr "Naslednja stran" + +msgid "Toggle navigation" +msgstr "Preklopi navigacijo" + +msgid "repository" +msgstr "odlagališče" + +msgid "suggest edit" +msgstr "predlagajte urejanje" + +msgid "open issue" +msgstr "odprto vprašanje" + +msgid "Launch" +msgstr "Kosilo" + +msgid "Print to PDF" +msgstr "Natisni v PDF" + +msgid "By the" +msgstr "Avtor" + +msgid "Last updated on" +msgstr "Nazadnje posodobljeno dne" + +msgid "Download source file" +msgstr "Prenesite izvorno datoteko" + +msgid "Download this page" +msgstr "Prenesite to stran" diff --git a/_static/locales/sr/LC_MESSAGES/booktheme.mo b/_static/locales/sr/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..ec740f48 Binary files /dev/null and b/_static/locales/sr/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/sr/LC_MESSAGES/booktheme.po b/_static/locales/sr/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..e809230c --- /dev/null +++ b/_static/locales/sr/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Тхеме би" + +msgid "Open an issue" +msgstr "Отворите издање" + +msgid "Contents" +msgstr "Садржај" + +msgid "Download notebook file" +msgstr "Преузмите датотеку бележнице" + +msgid "Sphinx Book Theme" +msgstr "Тема књиге Спхинк" + +msgid "Fullscreen mode" +msgstr "Режим целог екрана" + +msgid "Edit this page" +msgstr "Уредите ову страницу" + +msgid "By" +msgstr "Од стране" + +msgid "Copyright" +msgstr "Ауторско право" + +msgid "Source repository" +msgstr "Изворно спремиште" + +msgid "previous page" +msgstr "Претходна страница" + +msgid "next page" +msgstr "Следећа страна" + +msgid "Toggle navigation" +msgstr "Укључи / искључи навигацију" + +msgid "repository" +msgstr "спремиште" + +msgid "suggest edit" +msgstr "предложи уређивање" + +msgid "open issue" +msgstr "отворено издање" + +msgid "Launch" +msgstr "Лансирање" + +msgid "Print to PDF" +msgstr "Испис у ПДФ" + +msgid "By the" +msgstr "Од" + +msgid "Last updated on" +msgstr "Последње ажурирање" + +msgid "Download source file" +msgstr "Преузми изворну датотеку" + +msgid "Download this page" +msgstr "Преузмите ову страницу" diff --git a/_static/locales/sv/LC_MESSAGES/booktheme.mo b/_static/locales/sv/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..b07dc76f Binary files /dev/null and b/_static/locales/sv/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/sv/LC_MESSAGES/booktheme.po b/_static/locales/sv/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..2421b001 --- /dev/null +++ b/_static/locales/sv/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sv\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema av" + +msgid "Open an issue" +msgstr "Öppna en problemrapport" + +msgid "Contents" +msgstr "Innehåll" + +msgid "Download notebook file" +msgstr "Ladda ner notebook-fil" + +msgid "Sphinx Book Theme" +msgstr "Sphinx Boktema" + +msgid "Fullscreen mode" +msgstr "Fullskärmsläge" + +msgid "Edit this page" +msgstr "Redigera den här sidan" + +msgid "By" +msgstr "Av" + +msgid "Copyright" +msgstr "Upphovsrätt" + +msgid "Source repository" +msgstr "Källkodsrepositorium" + +msgid "previous page" +msgstr "föregående sida" + +msgid "next page" +msgstr "nästa sida" + +msgid "Toggle navigation" +msgstr "Växla navigering" + +msgid "repository" +msgstr "repositorium" + +msgid "suggest edit" +msgstr "föreslå ändring" + +msgid "open issue" +msgstr "öppna problemrapport" + +msgid "Launch" +msgstr "Öppna" + +msgid "Print to PDF" +msgstr "Skriv ut till PDF" + +msgid "By the" +msgstr "Av den" + +msgid "Last updated on" +msgstr "Senast uppdaterad den" + +msgid "Download source file" +msgstr "Ladda ner källfil" + +msgid "Download this page" +msgstr "Ladda ner den här sidan" diff --git a/_static/locales/ta/LC_MESSAGES/booktheme.mo b/_static/locales/ta/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..29f52e1f Binary files /dev/null and b/_static/locales/ta/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ta/LC_MESSAGES/booktheme.po b/_static/locales/ta/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..500042f4 --- /dev/null +++ b/_static/locales/ta/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ta\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "வழங்கிய தீம்" + +msgid "Open an issue" +msgstr "சிக்கலைத் திறக்கவும்" + +msgid "Download notebook file" +msgstr "நோட்புக் கோப்பைப் பதிவிறக்கவும்" + +msgid "Sphinx Book Theme" +msgstr "ஸ்பிங்க்ஸ் புத்தக தீம்" + +msgid "Edit this page" +msgstr "இந்தப் பக்கத்தைத் திருத்தவும்" + +msgid "By" +msgstr "வழங்கியவர்" + +msgid "Copyright" +msgstr "பதிப்புரிமை" + +msgid "Source repository" +msgstr "மூல களஞ்சியம்" + +msgid "previous page" +msgstr "முந்தைய பக்கம்" + +msgid "next page" +msgstr "அடுத்த பக்கம்" + +msgid "Toggle navigation" +msgstr "வழிசெலுத்தலை நிலைமாற்று" + +msgid "suggest edit" +msgstr "திருத்த பரிந்துரைக்கவும்" + +msgid "open issue" +msgstr "திறந்த பிரச்சினை" + +msgid "Launch" +msgstr "தொடங்க" + +msgid "Print to PDF" +msgstr "PDF இல் அச்சிடுக" + +msgid "By the" +msgstr "மூலம்" + +msgid "Last updated on" +msgstr "கடைசியாக புதுப்பிக்கப்பட்டது" + +msgid "Download source file" +msgstr "மூல கோப்பைப் பதிவிறக்குக" + +msgid "Download this page" +msgstr "இந்தப் பக்கத்தைப் பதிவிறக்கவும்" diff --git a/_static/locales/te/LC_MESSAGES/booktheme.mo b/_static/locales/te/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..0a5f4b46 Binary files /dev/null and b/_static/locales/te/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/te/LC_MESSAGES/booktheme.po b/_static/locales/te/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..b1afebba --- /dev/null +++ b/_static/locales/te/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: te\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "ద్వారా థీమ్" + +msgid "Open an issue" +msgstr "సమస్యను తెరవండి" + +msgid "Download notebook file" +msgstr "నోట్బుక్ ఫైల్ను డౌన్లోడ్ చేయండి" + +msgid "Sphinx Book Theme" +msgstr "సింహిక పుస్తక థీమ్" + +msgid "Edit this page" +msgstr "ఈ పేజీని సవరించండి" + +msgid "By" +msgstr "ద్వారా" + +msgid "Copyright" +msgstr "కాపీరైట్" + +msgid "Source repository" +msgstr "మూల రిపోజిటరీ" + +msgid "previous page" +msgstr "ముందు పేజి" + +msgid "next page" +msgstr "తరువాతి పేజీ" + +msgid "Toggle navigation" +msgstr "నావిగేషన్‌ను టోగుల్ చేయండి" + +msgid "suggest edit" +msgstr "సవరించమని సూచించండి" + +msgid "open issue" +msgstr "ఓపెన్ ఇష్యూ" + +msgid "Launch" +msgstr "ప్రారంభించండి" + +msgid "Print to PDF" +msgstr "PDF కి ముద్రించండి" + +msgid "By the" +msgstr "ద్వారా" + +msgid "Last updated on" +msgstr "చివరిగా నవీకరించబడింది" + +msgid "Download source file" +msgstr "మూల ఫైల్‌ను డౌన్‌లోడ్ చేయండి" + +msgid "Download this page" +msgstr "ఈ పేజీని డౌన్‌లోడ్ చేయండి" diff --git a/_static/locales/tg/LC_MESSAGES/booktheme.mo b/_static/locales/tg/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..b21c6c63 Binary files /dev/null and b/_static/locales/tg/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/tg/LC_MESSAGES/booktheme.po b/_static/locales/tg/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..29b8237b --- /dev/null +++ b/_static/locales/tg/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tg\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Мавзӯъи аз" + +msgid "Open an issue" +msgstr "Масъаларо кушоед" + +msgid "Contents" +msgstr "Мундариҷа" + +msgid "Download notebook file" +msgstr "Файли дафтарро зеркашӣ кунед" + +msgid "Sphinx Book Theme" +msgstr "Сфинкс Мавзӯи китоб" + +msgid "Fullscreen mode" +msgstr "Ҳолати экрани пурра" + +msgid "Edit this page" +msgstr "Ин саҳифаро таҳрир кунед" + +msgid "By" +msgstr "Бо" + +msgid "Copyright" +msgstr "Ҳуқуқи муаллиф" + +msgid "Source repository" +msgstr "Анбори манбаъ" + +msgid "previous page" +msgstr "саҳифаи қаблӣ" + +msgid "next page" +msgstr "саҳифаи оянда" + +msgid "Toggle navigation" +msgstr "Гузаришро иваз кунед" + +msgid "repository" +msgstr "анбор" + +msgid "suggest edit" +msgstr "пешниҳод вироиш" + +msgid "open issue" +msgstr "барориши кушод" + +msgid "Launch" +msgstr "Оғоз" + +msgid "Print to PDF" +msgstr "Чоп ба PDF" + +msgid "By the" +msgstr "Бо" + +msgid "Last updated on" +msgstr "Last навсозӣ дар" + +msgid "Download source file" +msgstr "Файли манбаъро зеркашӣ кунед" + +msgid "Download this page" +msgstr "Ин саҳифаро зеркашӣ кунед" diff --git a/_static/locales/th/LC_MESSAGES/booktheme.mo b/_static/locales/th/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..abede98a Binary files /dev/null and b/_static/locales/th/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/th/LC_MESSAGES/booktheme.po b/_static/locales/th/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..ac65ee05 --- /dev/null +++ b/_static/locales/th/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: th\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "ธีมโดย" + +msgid "Open an issue" +msgstr "เปิดปัญหา" + +msgid "Contents" +msgstr "สารบัญ" + +msgid "Download notebook file" +msgstr "ดาวน์โหลดไฟล์สมุดบันทึก" + +msgid "Sphinx Book Theme" +msgstr "ธีมหนังสือสฟิงซ์" + +msgid "Fullscreen mode" +msgstr "โหมดเต็มหน้าจอ" + +msgid "Edit this page" +msgstr "แก้ไขหน้านี้" + +msgid "By" +msgstr "โดย" + +msgid "Copyright" +msgstr "ลิขสิทธิ์" + +msgid "Source repository" +msgstr "ที่เก็บซอร์ส" + +msgid "previous page" +msgstr "หน้าที่แล้ว" + +msgid "next page" +msgstr "หน้าต่อไป" + +msgid "Toggle navigation" +msgstr "ไม่ต้องสลับช่องทาง" + +msgid "repository" +msgstr "ที่เก็บ" + +msgid "suggest edit" +msgstr "แนะนำแก้ไข" + +msgid "open issue" +msgstr "เปิดปัญหา" + +msgid "Launch" +msgstr "เปิด" + +msgid "Print to PDF" +msgstr "พิมพ์เป็น PDF" + +msgid "By the" +msgstr "โดย" + +msgid "Last updated on" +msgstr "ปรับปรุงล่าสุดเมื่อ" + +msgid "Download source file" +msgstr "ดาวน์โหลดไฟล์ต้นฉบับ" + +msgid "Download this page" +msgstr "ดาวน์โหลดหน้านี้" diff --git a/_static/locales/tl/LC_MESSAGES/booktheme.mo b/_static/locales/tl/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..8df1b733 Binary files /dev/null and b/_static/locales/tl/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/tl/LC_MESSAGES/booktheme.po b/_static/locales/tl/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..662d66ca --- /dev/null +++ b/_static/locales/tl/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tema ng" + +msgid "Open an issue" +msgstr "Magbukas ng isyu" + +msgid "Download notebook file" +msgstr "Mag-download ng file ng notebook" + +msgid "Sphinx Book Theme" +msgstr "Tema ng Sphinx Book" + +msgid "Edit this page" +msgstr "I-edit ang pahinang ito" + +msgid "By" +msgstr "Ni" + +msgid "Copyright" +msgstr "Copyright" + +msgid "Source repository" +msgstr "Pinagmulan ng imbakan" + +msgid "previous page" +msgstr "Nakaraang pahina" + +msgid "next page" +msgstr "Susunod na pahina" + +msgid "Toggle navigation" +msgstr "I-toggle ang pag-navigate" + +msgid "suggest edit" +msgstr "iminumungkahi i-edit" + +msgid "open issue" +msgstr "bukas na isyu" + +msgid "Launch" +msgstr "Ilunsad" + +msgid "Print to PDF" +msgstr "I-print sa PDF" + +msgid "By the" +msgstr "Sa pamamagitan ng" + +msgid "Last updated on" +msgstr "Huling na-update noong" + +msgid "Download source file" +msgstr "Mag-download ng file ng pinagmulan" + +msgid "Download this page" +msgstr "I-download ang pahinang ito" diff --git a/_static/locales/tr/LC_MESSAGES/booktheme.mo b/_static/locales/tr/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..029ae18a Binary files /dev/null and b/_static/locales/tr/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/tr/LC_MESSAGES/booktheme.po b/_static/locales/tr/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..d1ae7233 --- /dev/null +++ b/_static/locales/tr/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tr\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Tarafından tema" + +msgid "Open an issue" +msgstr "Bir sorunu açın" + +msgid "Contents" +msgstr "İçindekiler" + +msgid "Download notebook file" +msgstr "Defter dosyasını indirin" + +msgid "Sphinx Book Theme" +msgstr "Sfenks Kitap Teması" + +msgid "Fullscreen mode" +msgstr "Tam ekran modu" + +msgid "Edit this page" +msgstr "Bu sayfayı düzenle" + +msgid "By" +msgstr "Tarafından" + +msgid "Copyright" +msgstr "Telif hakkı" + +msgid "Source repository" +msgstr "Kaynak kod deposu" + +msgid "previous page" +msgstr "önceki sayfa" + +msgid "next page" +msgstr "sonraki Sayfa" + +msgid "Toggle navigation" +msgstr "Gezinmeyi değiştir" + +msgid "repository" +msgstr "depo" + +msgid "suggest edit" +msgstr "düzenleme öner" + +msgid "open issue" +msgstr "Açık konu" + +msgid "Launch" +msgstr "Başlatmak" + +msgid "Print to PDF" +msgstr "PDF olarak yazdır" + +msgid "By the" +msgstr "Tarafından" + +msgid "Last updated on" +msgstr "Son güncelleme tarihi" + +msgid "Download source file" +msgstr "Kaynak dosyayı indirin" + +msgid "Download this page" +msgstr "Bu sayfayı indirin" diff --git a/_static/locales/uk/LC_MESSAGES/booktheme.mo b/_static/locales/uk/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..16ab7890 Binary files /dev/null and b/_static/locales/uk/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/uk/LC_MESSAGES/booktheme.po b/_static/locales/uk/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..be49ab85 --- /dev/null +++ b/_static/locales/uk/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Тема від" + +msgid "Open an issue" +msgstr "Відкрийте випуск" + +msgid "Contents" +msgstr "Зміст" + +msgid "Download notebook file" +msgstr "Завантажте файл блокнота" + +msgid "Sphinx Book Theme" +msgstr "Тема книги \"Сфінкс\"" + +msgid "Fullscreen mode" +msgstr "Повноекранний режим" + +msgid "Edit this page" +msgstr "Редагувати цю сторінку" + +msgid "By" +msgstr "Автор" + +msgid "Copyright" +msgstr "Авторське право" + +msgid "Source repository" +msgstr "Джерело сховища" + +msgid "previous page" +msgstr "Попередня сторінка" + +msgid "next page" +msgstr "Наступна сторінка" + +msgid "Toggle navigation" +msgstr "Переключити навігацію" + +msgid "repository" +msgstr "сховище" + +msgid "suggest edit" +msgstr "запропонувати редагувати" + +msgid "open issue" +msgstr "відкритий випуск" + +msgid "Launch" +msgstr "Запуск" + +msgid "Print to PDF" +msgstr "Друк у форматі PDF" + +msgid "By the" +msgstr "По" + +msgid "Last updated on" +msgstr "Останнє оновлення:" + +msgid "Download source file" +msgstr "Завантажити вихідний файл" + +msgid "Download this page" +msgstr "Завантажте цю сторінку" diff --git a/_static/locales/ur/LC_MESSAGES/booktheme.mo b/_static/locales/ur/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..de8c84b9 Binary files /dev/null and b/_static/locales/ur/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/ur/LC_MESSAGES/booktheme.po b/_static/locales/ur/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..94bcab33 --- /dev/null +++ b/_static/locales/ur/LC_MESSAGES/booktheme.po @@ -0,0 +1,66 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ur\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "کے ذریعہ تھیم" + +msgid "Open an issue" +msgstr "ایک مسئلہ کھولیں" + +msgid "Download notebook file" +msgstr "نوٹ بک فائل ڈاؤن لوڈ کریں" + +msgid "Sphinx Book Theme" +msgstr "سپنکس بک تھیم" + +msgid "Edit this page" +msgstr "اس صفحے میں ترمیم کریں" + +msgid "By" +msgstr "بذریعہ" + +msgid "Copyright" +msgstr "کاپی رائٹ" + +msgid "Source repository" +msgstr "ماخذ ذخیرہ" + +msgid "previous page" +msgstr "سابقہ ​​صفحہ" + +msgid "next page" +msgstr "اگلا صفحہ" + +msgid "Toggle navigation" +msgstr "نیویگیشن ٹوگل کریں" + +msgid "suggest edit" +msgstr "ترمیم کی تجویز کریں" + +msgid "open issue" +msgstr "کھلا مسئلہ" + +msgid "Launch" +msgstr "لانچ کریں" + +msgid "Print to PDF" +msgstr "پی ڈی ایف پرنٹ کریں" + +msgid "By the" +msgstr "کی طرف" + +msgid "Last updated on" +msgstr "آخری بار تازہ کاری ہوئی" + +msgid "Download source file" +msgstr "سورس فائل ڈاؤن لوڈ کریں" + +msgid "Download this page" +msgstr "اس صفحے کو ڈاؤن لوڈ کریں" diff --git a/_static/locales/vi/LC_MESSAGES/booktheme.mo b/_static/locales/vi/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..2bb32555 Binary files /dev/null and b/_static/locales/vi/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/vi/LC_MESSAGES/booktheme.po b/_static/locales/vi/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..116236dc --- /dev/null +++ b/_static/locales/vi/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: vi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "Chủ đề của" + +msgid "Open an issue" +msgstr "Mở một vấn đề" + +msgid "Contents" +msgstr "Nội dung" + +msgid "Download notebook file" +msgstr "Tải xuống tệp sổ tay" + +msgid "Sphinx Book Theme" +msgstr "Chủ đề sách nhân sư" + +msgid "Fullscreen mode" +msgstr "Chế độ toàn màn hình" + +msgid "Edit this page" +msgstr "chỉnh sửa trang này" + +msgid "By" +msgstr "Bởi" + +msgid "Copyright" +msgstr "Bản quyền" + +msgid "Source repository" +msgstr "Kho nguồn" + +msgid "previous page" +msgstr "trang trước" + +msgid "next page" +msgstr "Trang tiếp theo" + +msgid "Toggle navigation" +msgstr "Chuyển đổi điều hướng thành" + +msgid "repository" +msgstr "kho" + +msgid "suggest edit" +msgstr "đề nghị chỉnh sửa" + +msgid "open issue" +msgstr "vấn đề mở" + +msgid "Launch" +msgstr "Phóng" + +msgid "Print to PDF" +msgstr "In sang PDF" + +msgid "By the" +msgstr "Bằng" + +msgid "Last updated on" +msgstr "Cập nhật lần cuối vào" + +msgid "Download source file" +msgstr "Tải xuống tệp nguồn" + +msgid "Download this page" +msgstr "Tải xuống trang này" diff --git a/_static/locales/zh_CN/LC_MESSAGES/booktheme.mo b/_static/locales/zh_CN/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..0e3235d0 Binary files /dev/null and b/_static/locales/zh_CN/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/zh_CN/LC_MESSAGES/booktheme.po b/_static/locales/zh_CN/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..4f4ab579 --- /dev/null +++ b/_static/locales/zh_CN/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "主题作者:" + +msgid "Open an issue" +msgstr "创建议题" + +msgid "Contents" +msgstr "目录" + +msgid "Download notebook file" +msgstr "下载笔记本文件" + +msgid "Sphinx Book Theme" +msgstr "Sphinx Book 主题" + +msgid "Fullscreen mode" +msgstr "全屏模式" + +msgid "Edit this page" +msgstr "编辑此页面" + +msgid "By" +msgstr "作者:" + +msgid "Copyright" +msgstr "版权" + +msgid "Source repository" +msgstr "源码库" + +msgid "previous page" +msgstr "上一页" + +msgid "next page" +msgstr "下一页" + +msgid "Toggle navigation" +msgstr "显示或隐藏导航栏" + +msgid "repository" +msgstr "仓库" + +msgid "suggest edit" +msgstr "提出修改建议" + +msgid "open issue" +msgstr "创建议题" + +msgid "Launch" +msgstr "启动" + +msgid "Print to PDF" +msgstr "列印成 PDF" + +msgid "By the" +msgstr "作者:" + +msgid "Last updated on" +msgstr "上次更新时间:" + +msgid "Download source file" +msgstr "下载源文件" + +msgid "Download this page" +msgstr "下载此页面" diff --git a/_static/locales/zh_TW/LC_MESSAGES/booktheme.mo b/_static/locales/zh_TW/LC_MESSAGES/booktheme.mo new file mode 100644 index 00000000..9116fa95 Binary files /dev/null and b/_static/locales/zh_TW/LC_MESSAGES/booktheme.mo differ diff --git a/_static/locales/zh_TW/LC_MESSAGES/booktheme.po b/_static/locales/zh_TW/LC_MESSAGES/booktheme.po new file mode 100644 index 00000000..42b43b86 --- /dev/null +++ b/_static/locales/zh_TW/LC_MESSAGES/booktheme.po @@ -0,0 +1,75 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Sphinx-Book-Theme\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_TW\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Theme by the" +msgstr "佈景主題作者:" + +msgid "Open an issue" +msgstr "開啟議題" + +msgid "Contents" +msgstr "目錄" + +msgid "Download notebook file" +msgstr "下載 Notebook 檔案" + +msgid "Sphinx Book Theme" +msgstr "Sphinx Book 佈景主題" + +msgid "Fullscreen mode" +msgstr "全螢幕模式" + +msgid "Edit this page" +msgstr "編輯此頁面" + +msgid "By" +msgstr "作者:" + +msgid "Copyright" +msgstr "Copyright" + +msgid "Source repository" +msgstr "來源儲存庫" + +msgid "previous page" +msgstr "上一頁" + +msgid "next page" +msgstr "下一頁" + +msgid "Toggle navigation" +msgstr "顯示或隱藏導覽列" + +msgid "repository" +msgstr "儲存庫" + +msgid "suggest edit" +msgstr "提出修改建議" + +msgid "open issue" +msgstr "公開的問題" + +msgid "Launch" +msgstr "啟動" + +msgid "Print to PDF" +msgstr "列印成 PDF" + +msgid "By the" +msgstr "作者:" + +msgid "Last updated on" +msgstr "最後更新時間:" + +msgid "Download source file" +msgstr "下載原始檔" + +msgid "Download this page" +msgstr "下載此頁面" diff --git a/_static/logo.png b/_static/logo.png new file mode 100644 index 00000000..3edf66eb Binary files /dev/null and b/_static/logo.png differ diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 00000000..33566310 --- /dev/null +++ b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/_static/play-solid.svg b/_static/play-solid.svg new file mode 100644 index 00000000..bcd81f7a --- /dev/null +++ b/_static/play-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..012e6a00 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,152 @@ +html[data-theme="light"] .highlight pre { line-height: 125%; } +html[data-theme="light"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight .hll { background-color: #fae4c2 } +html[data-theme="light"] .highlight { background: #fefefe; color: #080808 } +html[data-theme="light"] .highlight .c { color: #515151 } /* Comment */ +html[data-theme="light"] .highlight .err { color: #a12236 } /* Error */ +html[data-theme="light"] .highlight .k { color: #6730c5 } /* Keyword */ +html[data-theme="light"] .highlight .l { color: #7f4707 } /* Literal */ +html[data-theme="light"] .highlight .n { color: #080808 } /* Name */ +html[data-theme="light"] .highlight .o { color: #00622f } /* Operator */ +html[data-theme="light"] .highlight .p { color: #080808 } /* Punctuation */ +html[data-theme="light"] .highlight .ch { color: #515151 } /* Comment.Hashbang */ +html[data-theme="light"] .highlight .cm { color: #515151 } /* Comment.Multiline */ +html[data-theme="light"] .highlight .cp { color: #515151 } /* Comment.Preproc */ +html[data-theme="light"] .highlight .cpf { color: #515151 } /* Comment.PreprocFile */ +html[data-theme="light"] .highlight .c1 { color: #515151 } /* Comment.Single */ +html[data-theme="light"] .highlight .cs { color: #515151 } /* Comment.Special */ +html[data-theme="light"] .highlight .gd { color: #005b82 } /* Generic.Deleted */ +html[data-theme="light"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="light"] .highlight .gh { color: #005b82 } /* Generic.Heading */ +html[data-theme="light"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="light"] .highlight .gu { color: #005b82 } /* Generic.Subheading */ +html[data-theme="light"] .highlight .kc { color: #6730c5 } /* Keyword.Constant */ +html[data-theme="light"] .highlight .kd { color: #6730c5 } /* Keyword.Declaration */ +html[data-theme="light"] .highlight .kn { color: #6730c5 } /* Keyword.Namespace */ +html[data-theme="light"] .highlight .kp { color: #6730c5 } /* Keyword.Pseudo */ +html[data-theme="light"] .highlight .kr { color: #6730c5 } /* Keyword.Reserved */ +html[data-theme="light"] .highlight .kt { color: #7f4707 } /* Keyword.Type */ +html[data-theme="light"] .highlight .ld { color: #7f4707 } /* Literal.Date */ +html[data-theme="light"] .highlight .m { color: #7f4707 } /* Literal.Number */ +html[data-theme="light"] .highlight .s { color: #00622f } /* Literal.String */ +html[data-theme="light"] .highlight .na { color: #912583 } /* Name.Attribute */ +html[data-theme="light"] .highlight .nb { color: #7f4707 } /* Name.Builtin */ +html[data-theme="light"] .highlight .nc { color: #005b82 } /* Name.Class */ +html[data-theme="light"] .highlight .no { color: #005b82 } /* Name.Constant */ +html[data-theme="light"] .highlight .nd { color: #7f4707 } /* Name.Decorator */ +html[data-theme="light"] .highlight .ni { color: #00622f } /* Name.Entity */ +html[data-theme="light"] .highlight .ne { color: #6730c5 } /* Name.Exception */ +html[data-theme="light"] .highlight .nf { color: #005b82 } /* Name.Function */ +html[data-theme="light"] .highlight .nl { color: #7f4707 } /* Name.Label */ +html[data-theme="light"] .highlight .nn { color: #080808 } /* Name.Namespace */ +html[data-theme="light"] .highlight .nx { color: #080808 } /* Name.Other */ +html[data-theme="light"] .highlight .py { color: #005b82 } /* Name.Property */ +html[data-theme="light"] .highlight .nt { color: #005b82 } /* Name.Tag */ +html[data-theme="light"] .highlight .nv { color: #a12236 } /* Name.Variable */ +html[data-theme="light"] .highlight .ow { color: #6730c5 } /* Operator.Word */ +html[data-theme="light"] .highlight .pm { color: #080808 } /* Punctuation.Marker */ +html[data-theme="light"] .highlight .w { color: #080808 } /* Text.Whitespace */ +html[data-theme="light"] .highlight .mb { color: #7f4707 } /* Literal.Number.Bin */ +html[data-theme="light"] .highlight .mf { color: #7f4707 } /* Literal.Number.Float */ +html[data-theme="light"] .highlight .mh { color: #7f4707 } /* Literal.Number.Hex */ +html[data-theme="light"] .highlight .mi { color: #7f4707 } /* Literal.Number.Integer */ +html[data-theme="light"] .highlight .mo { color: #7f4707 } /* Literal.Number.Oct */ +html[data-theme="light"] .highlight .sa { color: #00622f } /* Literal.String.Affix */ +html[data-theme="light"] .highlight .sb { color: #00622f } /* Literal.String.Backtick */ +html[data-theme="light"] .highlight .sc { color: #00622f } /* Literal.String.Char */ +html[data-theme="light"] .highlight .dl { color: #00622f } /* Literal.String.Delimiter */ +html[data-theme="light"] .highlight .sd { color: #00622f } /* Literal.String.Doc */ +html[data-theme="light"] .highlight .s2 { color: #00622f } /* Literal.String.Double */ +html[data-theme="light"] .highlight .se { color: #00622f } /* Literal.String.Escape */ +html[data-theme="light"] .highlight .sh { color: #00622f } /* Literal.String.Heredoc */ +html[data-theme="light"] .highlight .si { color: #00622f } /* Literal.String.Interpol */ +html[data-theme="light"] .highlight .sx { color: #00622f } /* Literal.String.Other */ +html[data-theme="light"] .highlight .sr { color: #a12236 } /* Literal.String.Regex */ +html[data-theme="light"] .highlight .s1 { color: #00622f } /* Literal.String.Single */ +html[data-theme="light"] .highlight .ss { color: #005b82 } /* Literal.String.Symbol */ +html[data-theme="light"] .highlight .bp { color: #7f4707 } /* Name.Builtin.Pseudo */ +html[data-theme="light"] .highlight .fm { color: #005b82 } /* Name.Function.Magic */ +html[data-theme="light"] .highlight .vc { color: #a12236 } /* Name.Variable.Class */ +html[data-theme="light"] .highlight .vg { color: #a12236 } /* Name.Variable.Global */ +html[data-theme="light"] .highlight .vi { color: #a12236 } /* Name.Variable.Instance */ +html[data-theme="light"] .highlight .vm { color: #7f4707 } /* Name.Variable.Magic */ +html[data-theme="light"] .highlight .il { color: #7f4707 } /* Literal.Number.Integer.Long */ +html[data-theme="dark"] .highlight pre { line-height: 125%; } +html[data-theme="dark"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight .hll { background-color: #ffd9002e } +html[data-theme="dark"] .highlight { background: #2b2b2b; color: #f8f8f2 } +html[data-theme="dark"] .highlight .c { color: #ffd900 } /* Comment */ +html[data-theme="dark"] .highlight .err { color: #ffa07a } /* Error */ +html[data-theme="dark"] .highlight .k { color: #dcc6e0 } /* Keyword */ +html[data-theme="dark"] .highlight .l { color: #ffd900 } /* Literal */ +html[data-theme="dark"] .highlight .n { color: #f8f8f2 } /* Name */ +html[data-theme="dark"] .highlight .o { color: #abe338 } /* Operator */ +html[data-theme="dark"] .highlight .p { color: #f8f8f2 } /* Punctuation */ +html[data-theme="dark"] .highlight .ch { color: #ffd900 } /* Comment.Hashbang */ +html[data-theme="dark"] .highlight .cm { color: #ffd900 } /* Comment.Multiline */ +html[data-theme="dark"] .highlight .cp { color: #ffd900 } /* Comment.Preproc */ +html[data-theme="dark"] .highlight .cpf { color: #ffd900 } /* Comment.PreprocFile */ +html[data-theme="dark"] .highlight .c1 { color: #ffd900 } /* Comment.Single */ +html[data-theme="dark"] .highlight .cs { color: #ffd900 } /* Comment.Special */ +html[data-theme="dark"] .highlight .gd { color: #00e0e0 } /* Generic.Deleted */ +html[data-theme="dark"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="dark"] .highlight .gh { color: #00e0e0 } /* Generic.Heading */ +html[data-theme="dark"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="dark"] .highlight .gu { color: #00e0e0 } /* Generic.Subheading */ +html[data-theme="dark"] .highlight .kc { color: #dcc6e0 } /* Keyword.Constant */ +html[data-theme="dark"] .highlight .kd { color: #dcc6e0 } /* Keyword.Declaration */ +html[data-theme="dark"] .highlight .kn { color: #dcc6e0 } /* Keyword.Namespace */ +html[data-theme="dark"] .highlight .kp { color: #dcc6e0 } /* Keyword.Pseudo */ +html[data-theme="dark"] .highlight .kr { color: #dcc6e0 } /* Keyword.Reserved */ +html[data-theme="dark"] .highlight .kt { color: #ffd900 } /* Keyword.Type */ +html[data-theme="dark"] .highlight .ld { color: #ffd900 } /* Literal.Date */ +html[data-theme="dark"] .highlight .m { color: #ffd900 } /* Literal.Number */ +html[data-theme="dark"] .highlight .s { color: #abe338 } /* Literal.String */ +html[data-theme="dark"] .highlight .na { color: #ffd900 } /* Name.Attribute */ +html[data-theme="dark"] .highlight .nb { color: #ffd900 } /* Name.Builtin */ +html[data-theme="dark"] .highlight .nc { color: #00e0e0 } /* Name.Class */ +html[data-theme="dark"] .highlight .no { color: #00e0e0 } /* Name.Constant */ +html[data-theme="dark"] .highlight .nd { color: #ffd900 } /* Name.Decorator */ +html[data-theme="dark"] .highlight .ni { color: #abe338 } /* Name.Entity */ +html[data-theme="dark"] .highlight .ne { color: #dcc6e0 } /* Name.Exception */ +html[data-theme="dark"] .highlight .nf { color: #00e0e0 } /* Name.Function */ +html[data-theme="dark"] .highlight .nl { color: #ffd900 } /* Name.Label */ +html[data-theme="dark"] .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +html[data-theme="dark"] .highlight .nx { color: #f8f8f2 } /* Name.Other */ +html[data-theme="dark"] .highlight .py { color: #00e0e0 } /* Name.Property */ +html[data-theme="dark"] .highlight .nt { color: #00e0e0 } /* Name.Tag */ +html[data-theme="dark"] .highlight .nv { color: #ffa07a } /* Name.Variable */ +html[data-theme="dark"] .highlight .ow { color: #dcc6e0 } /* Operator.Word */ +html[data-theme="dark"] .highlight .pm { color: #f8f8f2 } /* Punctuation.Marker */ +html[data-theme="dark"] .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +html[data-theme="dark"] .highlight .mb { color: #ffd900 } /* Literal.Number.Bin */ +html[data-theme="dark"] .highlight .mf { color: #ffd900 } /* Literal.Number.Float */ +html[data-theme="dark"] .highlight .mh { color: #ffd900 } /* Literal.Number.Hex */ +html[data-theme="dark"] .highlight .mi { color: #ffd900 } /* Literal.Number.Integer */ +html[data-theme="dark"] .highlight .mo { color: #ffd900 } /* Literal.Number.Oct */ +html[data-theme="dark"] .highlight .sa { color: #abe338 } /* Literal.String.Affix */ +html[data-theme="dark"] .highlight .sb { color: #abe338 } /* Literal.String.Backtick */ +html[data-theme="dark"] .highlight .sc { color: #abe338 } /* Literal.String.Char */ +html[data-theme="dark"] .highlight .dl { color: #abe338 } /* Literal.String.Delimiter */ +html[data-theme="dark"] .highlight .sd { color: #abe338 } /* Literal.String.Doc */ +html[data-theme="dark"] .highlight .s2 { color: #abe338 } /* Literal.String.Double */ +html[data-theme="dark"] .highlight .se { color: #abe338 } /* Literal.String.Escape */ +html[data-theme="dark"] .highlight .sh { color: #abe338 } /* Literal.String.Heredoc */ +html[data-theme="dark"] .highlight .si { color: #abe338 } /* Literal.String.Interpol */ +html[data-theme="dark"] .highlight .sx { color: #abe338 } /* Literal.String.Other */ +html[data-theme="dark"] .highlight .sr { color: #ffa07a } /* Literal.String.Regex */ +html[data-theme="dark"] .highlight .s1 { color: #abe338 } /* Literal.String.Single */ +html[data-theme="dark"] .highlight .ss { color: #00e0e0 } /* Literal.String.Symbol */ +html[data-theme="dark"] .highlight .bp { color: #ffd900 } /* Name.Builtin.Pseudo */ +html[data-theme="dark"] .highlight .fm { color: #00e0e0 } /* Name.Function.Magic */ +html[data-theme="dark"] .highlight .vc { color: #ffa07a } /* Name.Variable.Class */ +html[data-theme="dark"] .highlight .vg { color: #ffa07a } /* Name.Variable.Global */ +html[data-theme="dark"] .highlight .vi { color: #ffa07a } /* Name.Variable.Instance */ +html[data-theme="dark"] .highlight .vm { color: #ffd900 } /* Name.Variable.Magic */ +html[data-theme="dark"] .highlight .il { color: #ffd900 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/sbt-webpack-macros.html b/_static/sbt-webpack-macros.html new file mode 100644 index 00000000..6cbf559f --- /dev/null +++ b/_static/sbt-webpack-macros.html @@ -0,0 +1,11 @@ + +{% macro head_pre_bootstrap() %} + +{% endmacro %} + +{% macro body_post() %} + +{% endmacro %} diff --git a/_static/scripts/bootstrap.js b/_static/scripts/bootstrap.js new file mode 100644 index 00000000..4e209b0e --- /dev/null +++ b/_static/scripts/bootstrap.js @@ -0,0 +1,3 @@ +/*! For license information please see bootstrap.js.LICENSE.txt */ +(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{afterMain:()=>E,afterRead:()=>v,afterWrite:()=>C,applyStyles:()=>$,arrow:()=>J,auto:()=>a,basePlacements:()=>l,beforeMain:()=>y,beforeRead:()=>_,beforeWrite:()=>A,bottom:()=>s,clippingParents:()=>d,computeStyles:()=>it,createPopper:()=>Dt,createPopperBase:()=>St,createPopperLite:()=>$t,detectOverflow:()=>_t,end:()=>h,eventListeners:()=>st,flip:()=>bt,hide:()=>wt,left:()=>r,main:()=>w,modifierPhases:()=>O,offset:()=>Et,placements:()=>g,popper:()=>f,popperGenerator:()=>Lt,popperOffsets:()=>At,preventOverflow:()=>Tt,read:()=>b,reference:()=>p,right:()=>o,start:()=>c,top:()=>n,variationPlacements:()=>m,viewport:()=>u,write:()=>T});var i={};t.r(i),t.d(i,{Alert:()=>Oe,Button:()=>ke,Carousel:()=>ri,Collapse:()=>yi,Dropdown:()=>Vi,Modal:()=>xn,Offcanvas:()=>Vn,Popover:()=>fs,ScrollSpy:()=>Ts,Tab:()=>Ks,Toast:()=>lo,Tooltip:()=>hs});var n="top",s="bottom",o="right",r="left",a="auto",l=[n,s,o,r],c="start",h="end",d="clippingParents",u="viewport",f="popper",p="reference",m=l.reduce((function(t,e){return t.concat([e+"-"+c,e+"-"+h])}),[]),g=[].concat(l,[a]).reduce((function(t,e){return t.concat([e,e+"-"+c,e+"-"+h])}),[]),_="beforeRead",b="read",v="afterRead",y="beforeMain",w="main",E="afterMain",A="beforeWrite",T="write",C="afterWrite",O=[_,b,v,y,w,E,A,T,C];function x(t){return t?(t.nodeName||"").toLowerCase():null}function k(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function L(t){return t instanceof k(t).Element||t instanceof Element}function S(t){return t instanceof k(t).HTMLElement||t instanceof HTMLElement}function D(t){return"undefined"!=typeof ShadowRoot&&(t instanceof k(t).ShadowRoot||t instanceof ShadowRoot)}const $={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];S(s)&&x(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});S(n)&&x(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function I(t){return t.split("-")[0]}var N=Math.max,P=Math.min,M=Math.round;function j(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function F(){return!/^((?!chrome|android).)*safari/i.test(j())}function H(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&S(t)&&(s=t.offsetWidth>0&&M(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&M(n.height)/t.offsetHeight||1);var r=(L(t)?k(t):window).visualViewport,a=!F()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function B(t){var e=H(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function W(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&D(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function z(t){return k(t).getComputedStyle(t)}function R(t){return["table","td","th"].indexOf(x(t))>=0}function q(t){return((L(t)?t.ownerDocument:t.document)||window.document).documentElement}function V(t){return"html"===x(t)?t:t.assignedSlot||t.parentNode||(D(t)?t.host:null)||q(t)}function Y(t){return S(t)&&"fixed"!==z(t).position?t.offsetParent:null}function K(t){for(var e=k(t),i=Y(t);i&&R(i)&&"static"===z(i).position;)i=Y(i);return i&&("html"===x(i)||"body"===x(i)&&"static"===z(i).position)?e:i||function(t){var e=/firefox/i.test(j());if(/Trident/i.test(j())&&S(t)&&"fixed"===z(t).position)return null;var i=V(t);for(D(i)&&(i=i.host);S(i)&&["html","body"].indexOf(x(i))<0;){var n=z(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Q(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function X(t,e,i){return N(t,P(e,i))}function U(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function G(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const J={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,a=t.name,c=t.options,h=i.elements.arrow,d=i.modifiersData.popperOffsets,u=I(i.placement),f=Q(u),p=[r,o].indexOf(u)>=0?"height":"width";if(h&&d){var m=function(t,e){return U("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:G(t,l))}(c.padding,i),g=B(h),_="y"===f?n:r,b="y"===f?s:o,v=i.rects.reference[p]+i.rects.reference[f]-d[f]-i.rects.popper[p],y=d[f]-i.rects.reference[f],w=K(h),E=w?"y"===f?w.clientHeight||0:w.clientWidth||0:0,A=v/2-y/2,T=m[_],C=E-g[p]-m[b],O=E/2-g[p]/2+A,x=X(T,O,C),k=f;i.modifiersData[a]=((e={})[k]=x,e.centerOffset=x-O,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&W(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Z(t){return t.split("-")[1]}var tt={top:"auto",right:"auto",bottom:"auto",left:"auto"};function et(t){var e,i=t.popper,a=t.popperRect,l=t.placement,c=t.variation,d=t.offsets,u=t.position,f=t.gpuAcceleration,p=t.adaptive,m=t.roundOffsets,g=t.isFixed,_=d.x,b=void 0===_?0:_,v=d.y,y=void 0===v?0:v,w="function"==typeof m?m({x:b,y}):{x:b,y};b=w.x,y=w.y;var E=d.hasOwnProperty("x"),A=d.hasOwnProperty("y"),T=r,C=n,O=window;if(p){var x=K(i),L="clientHeight",S="clientWidth";x===k(i)&&"static"!==z(x=q(i)).position&&"absolute"===u&&(L="scrollHeight",S="scrollWidth"),(l===n||(l===r||l===o)&&c===h)&&(C=s,y-=(g&&x===O&&O.visualViewport?O.visualViewport.height:x[L])-a.height,y*=f?1:-1),l!==r&&(l!==n&&l!==s||c!==h)||(T=o,b-=(g&&x===O&&O.visualViewport?O.visualViewport.width:x[S])-a.width,b*=f?1:-1)}var D,$=Object.assign({position:u},p&&tt),I=!0===m?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:M(i*s)/s||0,y:M(n*s)/s||0}}({x:b,y},k(i)):{x:b,y};return b=I.x,y=I.y,f?Object.assign({},$,((D={})[C]=A?"0":"",D[T]=E?"0":"",D.transform=(O.devicePixelRatio||1)<=1?"translate("+b+"px, "+y+"px)":"translate3d("+b+"px, "+y+"px, 0)",D)):Object.assign({},$,((e={})[C]=A?y+"px":"",e[T]=E?b+"px":"",e.transform="",e))}const it={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:I(e.placement),variation:Z(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,et(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,et(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var nt={passive:!0};const st={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=k(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,nt)})),a&&l.addEventListener("resize",i.update,nt),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,nt)})),a&&l.removeEventListener("resize",i.update,nt)}},data:{}};var ot={left:"right",right:"left",bottom:"top",top:"bottom"};function rt(t){return t.replace(/left|right|bottom|top/g,(function(t){return ot[t]}))}var at={start:"end",end:"start"};function lt(t){return t.replace(/start|end/g,(function(t){return at[t]}))}function ct(t){var e=k(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ht(t){return H(q(t)).left+ct(t).scrollLeft}function dt(t){var e=z(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function ut(t){return["html","body","#document"].indexOf(x(t))>=0?t.ownerDocument.body:S(t)&&dt(t)?t:ut(V(t))}function ft(t,e){var i;void 0===e&&(e=[]);var n=ut(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=k(n),r=s?[o].concat(o.visualViewport||[],dt(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ft(V(r)))}function pt(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function mt(t,e,i){return e===u?pt(function(t,e){var i=k(t),n=q(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=F();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+ht(t),y:l}}(t,i)):L(e)?function(t,e){var i=H(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):pt(function(t){var e,i=q(t),n=ct(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=N(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=N(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ht(t),l=-n.scrollTop;return"rtl"===z(s||i).direction&&(a+=N(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(q(t)))}function gt(t){var e,i=t.reference,a=t.element,l=t.placement,d=l?I(l):null,u=l?Z(l):null,f=i.x+i.width/2-a.width/2,p=i.y+i.height/2-a.height/2;switch(d){case n:e={x:f,y:i.y-a.height};break;case s:e={x:f,y:i.y+i.height};break;case o:e={x:i.x+i.width,y:p};break;case r:e={x:i.x-a.width,y:p};break;default:e={x:i.x,y:i.y}}var m=d?Q(d):null;if(null!=m){var g="y"===m?"height":"width";switch(u){case c:e[m]=e[m]-(i[g]/2-a[g]/2);break;case h:e[m]=e[m]+(i[g]/2-a[g]/2)}}return e}function _t(t,e){void 0===e&&(e={});var i=e,r=i.placement,a=void 0===r?t.placement:r,c=i.strategy,h=void 0===c?t.strategy:c,m=i.boundary,g=void 0===m?d:m,_=i.rootBoundary,b=void 0===_?u:_,v=i.elementContext,y=void 0===v?f:v,w=i.altBoundary,E=void 0!==w&&w,A=i.padding,T=void 0===A?0:A,C=U("number"!=typeof T?T:G(T,l)),O=y===f?p:f,k=t.rects.popper,D=t.elements[E?O:y],$=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ft(V(t)),i=["absolute","fixed"].indexOf(z(t).position)>=0&&S(t)?K(t):t;return L(i)?e.filter((function(t){return L(t)&&W(t,i)&&"body"!==x(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=mt(t,i,n);return e.top=N(s.top,e.top),e.right=P(s.right,e.right),e.bottom=P(s.bottom,e.bottom),e.left=N(s.left,e.left),e}),mt(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(L(D)?D:D.contextElement||q(t.elements.popper),g,b,h),I=H(t.elements.reference),M=gt({reference:I,element:k,strategy:"absolute",placement:a}),j=pt(Object.assign({},k,M)),F=y===f?j:I,B={top:$.top-F.top+C.top,bottom:F.bottom-$.bottom+C.bottom,left:$.left-F.left+C.left,right:F.right-$.right+C.right},R=t.modifiersData.offset;if(y===f&&R){var Y=R[a];Object.keys(B).forEach((function(t){var e=[o,s].indexOf(t)>=0?1:-1,i=[n,s].indexOf(t)>=0?"y":"x";B[t]+=Y[i]*e}))}return B}const bt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,h=t.name;if(!e.modifiersData[h]._skip){for(var d=i.mainAxis,u=void 0===d||d,f=i.altAxis,p=void 0===f||f,_=i.fallbackPlacements,b=i.padding,v=i.boundary,y=i.rootBoundary,w=i.altBoundary,E=i.flipVariations,A=void 0===E||E,T=i.allowedAutoPlacements,C=e.options.placement,O=I(C),x=_||(O!==C&&A?function(t){if(I(t)===a)return[];var e=rt(t);return[lt(t),e,lt(e)]}(C):[rt(C)]),k=[C].concat(x).reduce((function(t,i){return t.concat(I(i)===a?function(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,c=i.allowedAutoPlacements,h=void 0===c?g:c,d=Z(n),u=d?a?m:m.filter((function(t){return Z(t)===d})):l,f=u.filter((function(t){return h.indexOf(t)>=0}));0===f.length&&(f=u);var p=f.reduce((function(e,i){return e[i]=_t(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[I(i)],e}),{});return Object.keys(p).sort((function(t,e){return p[t]-p[e]}))}(e,{placement:i,boundary:v,rootBoundary:y,padding:b,flipVariations:A,allowedAutoPlacements:T}):i)}),[]),L=e.rects.reference,S=e.rects.popper,D=new Map,$=!0,N=k[0],P=0;P=0,B=H?"width":"height",W=_t(e,{placement:M,boundary:v,rootBoundary:y,altBoundary:w,padding:b}),z=H?F?o:r:F?s:n;L[B]>S[B]&&(z=rt(z));var R=rt(z),q=[];if(u&&q.push(W[j]<=0),p&&q.push(W[z]<=0,W[R]<=0),q.every((function(t){return t}))){N=M,$=!1;break}D.set(M,q)}if($)for(var V=function(t){var e=k.find((function(e){var i=D.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return N=e,"break"},Y=A?3:1;Y>0&&"break"!==V(Y);Y--);e.placement!==N&&(e.modifiersData[h]._skip=!0,e.placement=N,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function vt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function yt(t){return[n,o,s,r].some((function(e){return t[e]>=0}))}const wt={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=_t(e,{elementContext:"reference"}),a=_t(e,{altBoundary:!0}),l=vt(r,n),c=vt(a,s,o),h=yt(l),d=yt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Et={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,s=t.name,a=i.offset,l=void 0===a?[0,0]:a,c=g.reduce((function(t,i){return t[i]=function(t,e,i){var s=I(t),a=[r,n].indexOf(s)>=0?-1:1,l="function"==typeof i?i(Object.assign({},e,{placement:t})):i,c=l[0],h=l[1];return c=c||0,h=(h||0)*a,[r,o].indexOf(s)>=0?{x:h,y:c}:{x:c,y:h}}(i,e.rects,l),t}),{}),h=c[e.placement],d=h.x,u=h.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=d,e.modifiersData.popperOffsets.y+=u),e.modifiersData[s]=c}},At={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=gt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Tt={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,a=t.name,l=i.mainAxis,h=void 0===l||l,d=i.altAxis,u=void 0!==d&&d,f=i.boundary,p=i.rootBoundary,m=i.altBoundary,g=i.padding,_=i.tether,b=void 0===_||_,v=i.tetherOffset,y=void 0===v?0:v,w=_t(e,{boundary:f,rootBoundary:p,padding:g,altBoundary:m}),E=I(e.placement),A=Z(e.placement),T=!A,C=Q(E),O="x"===C?"y":"x",x=e.modifiersData.popperOffsets,k=e.rects.reference,L=e.rects.popper,S="function"==typeof y?y(Object.assign({},e.rects,{placement:e.placement})):y,D="number"==typeof S?{mainAxis:S,altAxis:S}:Object.assign({mainAxis:0,altAxis:0},S),$=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,M={x:0,y:0};if(x){if(h){var j,F="y"===C?n:r,H="y"===C?s:o,W="y"===C?"height":"width",z=x[C],R=z+w[F],q=z-w[H],V=b?-L[W]/2:0,Y=A===c?k[W]:L[W],U=A===c?-L[W]:-k[W],G=e.elements.arrow,J=b&&G?B(G):{width:0,height:0},tt=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},et=tt[F],it=tt[H],nt=X(0,k[W],J[W]),st=T?k[W]/2-V-nt-et-D.mainAxis:Y-nt-et-D.mainAxis,ot=T?-k[W]/2+V+nt+it+D.mainAxis:U+nt+it+D.mainAxis,rt=e.elements.arrow&&K(e.elements.arrow),at=rt?"y"===C?rt.clientTop||0:rt.clientLeft||0:0,lt=null!=(j=null==$?void 0:$[C])?j:0,ct=z+ot-lt,ht=X(b?P(R,z+st-lt-at):R,z,b?N(q,ct):q);x[C]=ht,M[C]=ht-z}if(u){var dt,ut="x"===C?n:r,ft="x"===C?s:o,pt=x[O],mt="y"===O?"height":"width",gt=pt+w[ut],bt=pt-w[ft],vt=-1!==[n,r].indexOf(E),yt=null!=(dt=null==$?void 0:$[O])?dt:0,wt=vt?gt:pt-k[mt]-L[mt]-yt+D.altAxis,Et=vt?pt+k[mt]+L[mt]-yt-D.altAxis:bt,At=b&&vt?function(t,e,i){var n=X(t,e,i);return n>i?i:n}(wt,pt,Et):X(b?wt:gt,pt,b?Et:bt);x[O]=At,M[O]=At-pt}e.modifiersData[a]=M}},requiresIfExists:["offset"]};function Ct(t,e,i){void 0===i&&(i=!1);var n,s,o=S(e),r=S(e)&&function(t){var e=t.getBoundingClientRect(),i=M(e.width)/t.offsetWidth||1,n=M(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=q(e),l=H(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==x(e)||dt(a))&&(c=(n=e)!==k(n)&&S(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ct(n)),S(e)?((h=H(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=ht(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function Ot(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var xt={placement:"bottom",modifiers:[],strategy:"absolute"};function kt(){for(var t=arguments.length,e=new Array(t),i=0;iIt.has(t)&&It.get(t).get(e)||null,remove(t,e){if(!It.has(t))return;const i=It.get(t);i.delete(e),0===i.size&&It.delete(t)}},Pt="transitionend",Mt=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),jt=t=>{t.dispatchEvent(new Event(Pt))},Ft=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),Ht=t=>Ft(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(Mt(t)):null,Bt=t=>{if(!Ft(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},Wt=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),zt=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?zt(t.parentNode):null},Rt=()=>{},qt=t=>{t.offsetHeight},Vt=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,Yt=[],Kt=()=>"rtl"===document.documentElement.dir,Qt=t=>{var e;e=()=>{const e=Vt();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(Yt.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of Yt)t()})),Yt.push(e)):e()},Xt=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,Ut=(t,e,i=!0)=>{if(!i)return void Xt(t);const n=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let s=!1;const o=({target:i})=>{i===e&&(s=!0,e.removeEventListener(Pt,o),Xt(t))};e.addEventListener(Pt,o),setTimeout((()=>{s||jt(e)}),n)},Gt=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},Jt=/[^.]*(?=\..*)\.|.*/,Zt=/\..*/,te=/::\d+$/,ee={};let ie=1;const ne={mouseenter:"mouseover",mouseleave:"mouseout"},se=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function oe(t,e){return e&&`${e}::${ie++}`||t.uidEvent||ie++}function re(t){const e=oe(t);return t.uidEvent=e,ee[e]=ee[e]||{},ee[e]}function ae(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function le(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=ue(t);return se.has(o)||(o=t),[n,s,o]}function ce(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=le(e,i,n);if(e in ne){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=re(t),c=l[a]||(l[a]={}),h=ae(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=oe(r,e.replace(Jt,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return pe(s,{delegateTarget:r}),n.oneOff&&fe.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return pe(n,{delegateTarget:t}),i.oneOff&&fe.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function he(t,e,i,n,s){const o=ae(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function de(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&he(t,e,i,r.callable,r.delegationSelector)}function ue(t){return t=t.replace(Zt,""),ne[t]||t}const fe={on(t,e,i,n){ce(t,e,i,n,!1)},one(t,e,i,n){ce(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=le(e,i,n),a=r!==e,l=re(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))de(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(te,"");a&&!e.includes(s)||he(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;he(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=Vt();let s=null,o=!0,r=!0,a=!1;e!==ue(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=pe(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function pe(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function me(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function ge(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const _e={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${ge(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${ge(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=me(t.dataset[n])}return e},getDataAttribute:(t,e)=>me(t.getAttribute(`data-bs-${ge(e)}`))};class be{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=Ft(e)?_e.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...Ft(e)?_e.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],o=Ft(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${o}" but expected type "${s}".`)}var i}}class ve extends be{constructor(t,e){super(),(t=Ht(t))&&(this._element=t,this._config=this._getConfig(e),Nt.set(this._element,this.constructor.DATA_KEY,this))}dispose(){Nt.remove(this._element,this.constructor.DATA_KEY),fe.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){Ut(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return Nt.get(Ht(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const ye=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?Mt(i.trim()):null}return e},we={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!Wt(t)&&Bt(t)))},getSelectorFromElement(t){const e=ye(t);return e&&we.findOne(e)?e:null},getElementFromSelector(t){const e=ye(t);return e?we.findOne(e):null},getMultipleElementsFromSelector(t){const e=ye(t);return e?we.find(e):[]}},Ee=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;fe.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),Wt(this))return;const s=we.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},Ae=".bs.alert",Te=`close${Ae}`,Ce=`closed${Ae}`;class Oe extends ve{static get NAME(){return"alert"}close(){if(fe.trigger(this._element,Te).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),fe.trigger(this._element,Ce),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Oe.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}Ee(Oe,"close"),Qt(Oe);const xe='[data-bs-toggle="button"]';class ke extends ve{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=ke.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}fe.on(document,"click.bs.button.data-api",xe,(t=>{t.preventDefault();const e=t.target.closest(xe);ke.getOrCreateInstance(e).toggle()})),Qt(ke);const Le=".bs.swipe",Se=`touchstart${Le}`,De=`touchmove${Le}`,$e=`touchend${Le}`,Ie=`pointerdown${Le}`,Ne=`pointerup${Le}`,Pe={endCallback:null,leftCallback:null,rightCallback:null},Me={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class je extends be{constructor(t,e){super(),this._element=t,t&&je.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Pe}static get DefaultType(){return Me}static get NAME(){return"swipe"}dispose(){fe.off(this._element,Le)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),Xt(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&Xt(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(fe.on(this._element,Ie,(t=>this._start(t))),fe.on(this._element,Ne,(t=>this._end(t))),this._element.classList.add("pointer-event")):(fe.on(this._element,Se,(t=>this._start(t))),fe.on(this._element,De,(t=>this._move(t))),fe.on(this._element,$e,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const Fe=".bs.carousel",He=".data-api",Be="next",We="prev",ze="left",Re="right",qe=`slide${Fe}`,Ve=`slid${Fe}`,Ye=`keydown${Fe}`,Ke=`mouseenter${Fe}`,Qe=`mouseleave${Fe}`,Xe=`dragstart${Fe}`,Ue=`load${Fe}${He}`,Ge=`click${Fe}${He}`,Je="carousel",Ze="active",ti=".active",ei=".carousel-item",ii=ti+ei,ni={ArrowLeft:Re,ArrowRight:ze},si={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},oi={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ri extends ve{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=we.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===Je&&this.cycle()}static get Default(){return si}static get DefaultType(){return oi}static get NAME(){return"carousel"}next(){this._slide(Be)}nextWhenVisible(){!document.hidden&&Bt(this._element)&&this.next()}prev(){this._slide(We)}pause(){this._isSliding&&jt(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?fe.one(this._element,Ve,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void fe.one(this._element,Ve,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?Be:We;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&fe.on(this._element,Ye,(t=>this._keydown(t))),"hover"===this._config.pause&&(fe.on(this._element,Ke,(()=>this.pause())),fe.on(this._element,Qe,(()=>this._maybeEnableCycle()))),this._config.touch&&je.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of we.find(".carousel-item img",this._element))fe.on(t,Xe,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ze)),rightCallback:()=>this._slide(this._directionToOrder(Re)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new je(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=ni[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=we.findOne(ti,this._indicatorsElement);e.classList.remove(Ze),e.removeAttribute("aria-current");const i=we.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(Ze),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===Be,s=e||Gt(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>fe.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(qe).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),qt(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(Ze),i.classList.remove(Ze,c,l),this._isSliding=!1,r(Ve)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return we.findOne(ii,this._element)}_getItems(){return we.find(ei,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return Kt()?t===ze?We:Be:t===ze?Be:We}_orderToDirection(t){return Kt()?t===We?ze:Re:t===We?Re:ze}static jQueryInterface(t){return this.each((function(){const e=ri.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}fe.on(document,Ge,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=we.getElementFromSelector(this);if(!e||!e.classList.contains(Je))return;t.preventDefault();const i=ri.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===_e.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),fe.on(window,Ue,(()=>{const t=we.find('[data-bs-ride="carousel"]');for(const e of t)ri.getOrCreateInstance(e)})),Qt(ri);const ai=".bs.collapse",li=`show${ai}`,ci=`shown${ai}`,hi=`hide${ai}`,di=`hidden${ai}`,ui=`click${ai}.data-api`,fi="show",pi="collapse",mi="collapsing",gi=`:scope .${pi} .${pi}`,_i='[data-bs-toggle="collapse"]',bi={parent:null,toggle:!0},vi={parent:"(null|element)",toggle:"boolean"};class yi extends ve{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=we.find(_i);for(const t of i){const e=we.getSelectorFromElement(t),i=we.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return bi}static get DefaultType(){return vi}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>yi.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(fe.trigger(this._element,li).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(pi),this._element.classList.add(mi),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(mi),this._element.classList.add(pi,fi),this._element.style[e]="",fe.trigger(this._element,ci)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(fe.trigger(this._element,hi).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,qt(this._element),this._element.classList.add(mi),this._element.classList.remove(pi,fi);for(const t of this._triggerArray){const e=we.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(mi),this._element.classList.add(pi),fe.trigger(this._element,di)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(fi)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=Ht(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(_i);for(const e of t){const t=we.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=we.find(gi,this._config.parent);return we.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=yi.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}fe.on(document,ui,_i,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of we.getMultipleElementsFromSelector(this))yi.getOrCreateInstance(t,{toggle:!1}).toggle()})),Qt(yi);const wi="dropdown",Ei=".bs.dropdown",Ai=".data-api",Ti="ArrowUp",Ci="ArrowDown",Oi=`hide${Ei}`,xi=`hidden${Ei}`,ki=`show${Ei}`,Li=`shown${Ei}`,Si=`click${Ei}${Ai}`,Di=`keydown${Ei}${Ai}`,$i=`keyup${Ei}${Ai}`,Ii="show",Ni='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Pi=`${Ni}.${Ii}`,Mi=".dropdown-menu",ji=Kt()?"top-end":"top-start",Fi=Kt()?"top-start":"top-end",Hi=Kt()?"bottom-end":"bottom-start",Bi=Kt()?"bottom-start":"bottom-end",Wi=Kt()?"left-start":"right-start",zi=Kt()?"right-start":"left-start",Ri={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},qi={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class Vi extends ve{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=we.next(this._element,Mi)[0]||we.prev(this._element,Mi)[0]||we.findOne(Mi,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Ri}static get DefaultType(){return qi}static get NAME(){return wi}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Wt(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!fe.trigger(this._element,ki,t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))fe.on(t,"mouseover",Rt);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Ii),this._element.classList.add(Ii),fe.trigger(this._element,Li,t)}}hide(){if(Wt(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!fe.trigger(this._element,Oi,t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))fe.off(t,"mouseover",Rt);this._popper&&this._popper.destroy(),this._menu.classList.remove(Ii),this._element.classList.remove(Ii),this._element.setAttribute("aria-expanded","false"),_e.removeDataAttribute(this._menu,"popper"),fe.trigger(this._element,xi,t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!Ft(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${wi.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===e)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:Ft(this._config.reference)?t=Ht(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const i=this._getPopperConfig();this._popper=Dt(t,this._menu,i)}_isShown(){return this._menu.classList.contains(Ii)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Wi;if(t.classList.contains("dropstart"))return zi;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?Fi:ji:e?Bi:Hi}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(_e.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...Xt(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=we.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>Bt(t)));i.length&&Gt(i,e,t===Ci,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Vi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=we.find(Pi);for(const i of e){const e=Vi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ti,Ci].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ni)?this:we.prev(this,Ni)[0]||we.next(this,Ni)[0]||we.findOne(Ni,t.delegateTarget.parentNode),o=Vi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}fe.on(document,Di,Ni,Vi.dataApiKeydownHandler),fe.on(document,Di,Mi,Vi.dataApiKeydownHandler),fe.on(document,Si,Vi.clearMenus),fe.on(document,$i,Vi.clearMenus),fe.on(document,Si,Ni,(function(t){t.preventDefault(),Vi.getOrCreateInstance(this).toggle()})),Qt(Vi);const Yi="backdrop",Ki="show",Qi=`mousedown.bs.${Yi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Ui={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Gi extends be{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Ui}static get NAME(){return Yi}show(t){if(!this._config.isVisible)return void Xt(t);this._append();const e=this._getElement();this._config.isAnimated&&qt(e),e.classList.add(Ki),this._emulateAnimation((()=>{Xt(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),Xt(t)}))):Xt(t)}dispose(){this._isAppended&&(fe.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=Ht(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),fe.on(t,Qi,(()=>{Xt(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){Ut(t,this._getElement(),this._config.isAnimated)}}const Ji=".bs.focustrap",Zi=`focusin${Ji}`,tn=`keydown.tab${Ji}`,en="backward",nn={autofocus:!0,trapElement:null},sn={autofocus:"boolean",trapElement:"element"};class on extends be{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return nn}static get DefaultType(){return sn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),fe.off(document,Ji),fe.on(document,Zi,(t=>this._handleFocusin(t))),fe.on(document,tn,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,fe.off(document,Ji))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=we.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===en?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?en:"forward")}}const rn=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",an=".sticky-top",ln="padding-right",cn="margin-right";class hn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,ln,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,ln),this._resetElementAttributes(rn,ln),this._resetElementAttributes(an,cn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&_e.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=_e.getDataAttribute(t,e);null!==i?(_e.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(Ft(t))e(t);else for(const i of we.find(t,this._element))e(i)}}const dn=".bs.modal",un=`hide${dn}`,fn=`hidePrevented${dn}`,pn=`hidden${dn}`,mn=`show${dn}`,gn=`shown${dn}`,_n=`resize${dn}`,bn=`click.dismiss${dn}`,vn=`mousedown.dismiss${dn}`,yn=`keydown.dismiss${dn}`,wn=`click${dn}.data-api`,En="modal-open",An="show",Tn="modal-static",Cn={backdrop:!0,focus:!0,keyboard:!0},On={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class xn extends ve{constructor(t,e){super(t,e),this._dialog=we.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new hn,this._addEventListeners()}static get Default(){return Cn}static get DefaultType(){return On}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||fe.trigger(this._element,mn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(fe.trigger(this._element,un).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){fe.off(window,dn),fe.off(this._dialog,dn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Gi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new on({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=we.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),qt(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,fe.trigger(this._element,gn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){fe.on(this._element,yn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),fe.on(window,_n,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),fe.on(this._element,vn,(t=>{fe.one(this._element,bn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),fe.trigger(this._element,pn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(fe.trigger(this._element,fn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Tn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Tn),this._queueCallback((()=>{this._element.classList.remove(Tn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=Kt()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=Kt()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=xn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}fe.on(document,wn,'[data-bs-toggle="modal"]',(function(t){const e=we.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),fe.one(e,mn,(t=>{t.defaultPrevented||fe.one(e,pn,(()=>{Bt(this)&&this.focus()}))}));const i=we.findOne(".modal.show");i&&xn.getInstance(i).hide(),xn.getOrCreateInstance(e).toggle(this)})),Ee(xn),Qt(xn);const kn=".bs.offcanvas",Ln=".data-api",Sn=`load${kn}${Ln}`,Dn="show",$n="showing",In="hiding",Nn=".offcanvas.show",Pn=`show${kn}`,Mn=`shown${kn}`,jn=`hide${kn}`,Fn=`hidePrevented${kn}`,Hn=`hidden${kn}`,Bn=`resize${kn}`,Wn=`click${kn}${Ln}`,zn=`keydown.dismiss${kn}`,Rn={backdrop:!0,keyboard:!0,scroll:!1},qn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Vn extends ve{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return Rn}static get DefaultType(){return qn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||fe.trigger(this._element,Pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new hn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($n),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Dn),this._element.classList.remove($n),fe.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(fe.trigger(this._element,jn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(In),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Dn,In),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new hn).reset(),fe.trigger(this._element,Hn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Gi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():fe.trigger(this._element,Fn)}:null})}_initializeFocusTrap(){return new on({trapElement:this._element})}_addEventListeners(){fe.on(this._element,zn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():fe.trigger(this._element,Fn))}))}static jQueryInterface(t){return this.each((function(){const e=Vn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}fe.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=we.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),Wt(this))return;fe.one(e,Hn,(()=>{Bt(this)&&this.focus()}));const i=we.findOne(Nn);i&&i!==e&&Vn.getInstance(i).hide(),Vn.getOrCreateInstance(e).toggle(this)})),fe.on(window,Sn,(()=>{for(const t of we.find(Nn))Vn.getOrCreateInstance(t).show()})),fe.on(window,Bn,(()=>{for(const t of we.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Vn.getOrCreateInstance(t).hide()})),Ee(Vn),Qt(Vn);const Yn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Un={allowList:Yn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Gn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Jn={entry:"(string|element|function|null)",selector:"(string|element)"};class Zn extends be{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Un}static get DefaultType(){return Gn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Jn)}_setContent(t,e,i){const n=we.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?Ft(e)?this._putElementInTemplate(Ht(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return Xt(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const ts=new Set(["sanitize","allowList","sanitizeFn"]),es="fade",is="show",ns=".modal",ss="hide.bs.modal",os="hover",rs="focus",as={AUTO:"auto",TOP:"top",RIGHT:Kt()?"left":"right",BOTTOM:"bottom",LEFT:Kt()?"right":"left"},ls={allowList:Yn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},cs={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class hs extends ve{constructor(t,i){if(void 0===e)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,i),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return ls}static get DefaultType(){return cs}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),fe.off(this._element.closest(ns),ss,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=fe.trigger(this._element,this.constructor.eventName("show")),e=(zt(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),fe.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(is),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))fe.on(t,"mouseover",Rt);this._queueCallback((()=>{fe.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!fe.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(is),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))fe.off(t,"mouseover",Rt);this._activeTrigger.click=!1,this._activeTrigger[rs]=!1,this._activeTrigger[os]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),fe.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(es,is),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(es),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Zn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(es)}_isShown(){return this.tip&&this.tip.classList.contains(is)}_createPopper(t){const e=Xt(this._config.placement,[this,t,this._element]),i=as[e.toUpperCase()];return Dt(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return Xt(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...Xt(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)fe.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===os?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===os?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");fe.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?rs:os]=!0,e._enter()})),fe.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?rs:os]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},fe.on(this._element.closest(ns),ss,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=_e.getDataAttributes(this._element);for(const t of Object.keys(e))ts.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:Ht(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=hs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Qt(hs);const ds={...hs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},us={...hs.DefaultType,content:"(null|string|element|function)"};class fs extends hs{static get Default(){return ds}static get DefaultType(){return us}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=fs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Qt(fs);const ps=".bs.scrollspy",ms=`activate${ps}`,gs=`click${ps}`,_s=`load${ps}.data-api`,bs="active",vs="[href]",ys=".nav-link",ws=`${ys}, .nav-item > ${ys}, .list-group-item`,Es={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Ts extends ve{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Es}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=Ht(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(fe.off(this._config.target,gs),fe.on(this._config.target,gs,vs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=we.find(vs,this._config.target);for(const e of t){if(!e.hash||Wt(e))continue;const t=we.findOne(decodeURI(e.hash),this._element);Bt(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(bs),this._activateParents(t),fe.trigger(this._element,ms,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))we.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(bs);else for(const e of we.parents(t,".nav, .list-group"))for(const t of we.prev(e,ws))t.classList.add(bs)}_clearActiveClass(t){t.classList.remove(bs);const e=we.find(`${vs}.${bs}`,t);for(const t of e)t.classList.remove(bs)}static jQueryInterface(t){return this.each((function(){const e=Ts.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}fe.on(window,_s,(()=>{for(const t of we.find('[data-bs-spy="scroll"]'))Ts.getOrCreateInstance(t)})),Qt(Ts);const Cs=".bs.tab",Os=`hide${Cs}`,xs=`hidden${Cs}`,ks=`show${Cs}`,Ls=`shown${Cs}`,Ss=`click${Cs}`,Ds=`keydown${Cs}`,$s=`load${Cs}`,Is="ArrowLeft",Ns="ArrowRight",Ps="ArrowUp",Ms="ArrowDown",js="Home",Fs="End",Hs="active",Bs="fade",Ws="show",zs=".dropdown-toggle",Rs=`:not(${zs})`,qs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Vs=`.nav-link${Rs}, .list-group-item${Rs}, [role="tab"]${Rs}, ${qs}`,Ys=`.${Hs}[data-bs-toggle="tab"], .${Hs}[data-bs-toggle="pill"], .${Hs}[data-bs-toggle="list"]`;class Ks extends ve{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),fe.on(this._element,Ds,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?fe.trigger(e,Os,{relatedTarget:t}):null;fe.trigger(t,ks,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Hs),this._activate(we.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),fe.trigger(t,Ls,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Bs)))}_deactivate(t,e){t&&(t.classList.remove(Hs),t.blur(),this._deactivate(we.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),fe.trigger(t,xs,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Bs)))}_keydown(t){if(![Is,Ns,Ps,Ms,js,Fs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!Wt(t)));let i;if([js,Fs].includes(t.key))i=e[t.key===js?0:e.length-1];else{const n=[Ns,Ms].includes(t.key);i=Gt(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Ks.getOrCreateInstance(i).show())}_getChildren(){return we.find(Vs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=we.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=we.findOne(t,i);s&&s.classList.toggle(n,e)};n(zs,Hs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Hs)}_getInnerElement(t){return t.matches(Vs)?t:we.findOne(Vs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Ks.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}fe.on(document,Ss,qs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),Wt(this)||Ks.getOrCreateInstance(this).show()})),fe.on(window,$s,(()=>{for(const t of we.find(Ys))Ks.getOrCreateInstance(t)})),Qt(Ks);const Qs=".bs.toast",Xs=`mouseover${Qs}`,Us=`mouseout${Qs}`,Gs=`focusin${Qs}`,Js=`focusout${Qs}`,Zs=`hide${Qs}`,to=`hidden${Qs}`,eo=`show${Qs}`,io=`shown${Qs}`,no="hide",so="show",oo="showing",ro={animation:"boolean",autohide:"boolean",delay:"number"},ao={animation:!0,autohide:!0,delay:5e3};class lo extends ve{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return ao}static get DefaultType(){return ro}static get NAME(){return"toast"}show(){fe.trigger(this._element,eo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(no),qt(this._element),this._element.classList.add(so,oo),this._queueCallback((()=>{this._element.classList.remove(oo),fe.trigger(this._element,io),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(fe.trigger(this._element,Zs).defaultPrevented||(this._element.classList.add(oo),this._queueCallback((()=>{this._element.classList.add(no),this._element.classList.remove(oo,so),fe.trigger(this._element,to)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(so),super.dispose()}isShown(){return this._element.classList.contains(so)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){fe.on(this._element,Xs,(t=>this._onInteraction(t,!0))),fe.on(this._element,Us,(t=>this._onInteraction(t,!1))),fe.on(this._element,Gs,(t=>this._onInteraction(t,!0))),fe.on(this._element,Js,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=lo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}function co(t){"loading"!=document.readyState?t():document.addEventListener("DOMContentLoaded",t)}Ee(lo),Qt(lo),co((function(){[].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')).map((function(t){return new hs(t,{delay:{show:500,hide:100}})}))})),co((function(){document.getElementById("pst-back-to-top").addEventListener("click",(function(){document.body.scrollTop=0,document.documentElement.scrollTop=0}))})),co((function(){var t=document.getElementById("pst-back-to-top"),e=document.getElementsByClassName("bd-header")[0].getBoundingClientRect();window.addEventListener("scroll",(function(){this.oldScroll>this.scrollY&&this.scrollY>e.bottom?t.style.display="block":t.style.display="none",this.oldScroll=this.scrollY}))})),window.bootstrap=i})(); +//# sourceMappingURL=bootstrap.js.map \ No newline at end of file diff --git a/_static/scripts/bootstrap.js.LICENSE.txt b/_static/scripts/bootstrap.js.LICENSE.txt new file mode 100644 index 00000000..10f979d0 --- /dev/null +++ b/_static/scripts/bootstrap.js.LICENSE.txt @@ -0,0 +1,5 @@ +/*! + * Bootstrap v5.3.2 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ diff --git a/_static/scripts/bootstrap.js.map b/_static/scripts/bootstrap.js.map new file mode 100644 index 00000000..64e212b1 --- /dev/null +++ b/_static/scripts/bootstrap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/bootstrap.js","mappings":";mBACA,IAAIA,EAAsB,CCA1BA,EAAwB,CAACC,EAASC,KACjC,IAAI,IAAIC,KAAOD,EACXF,EAAoBI,EAAEF,EAAYC,KAASH,EAAoBI,EAAEH,EAASE,IAC5EE,OAAOC,eAAeL,EAASE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAE1E,ECNDH,EAAwB,CAACS,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFV,EAAyBC,IACH,oBAAXa,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeL,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeL,EAAS,aAAc,CAAEe,OAAO,GAAO,01BCLvD,IAAI,EAAM,MACNC,EAAS,SACTC,EAAQ,QACRC,EAAO,OACPC,EAAO,OACPC,EAAiB,CAAC,EAAKJ,EAAQC,EAAOC,GACtCG,EAAQ,QACRC,EAAM,MACNC,EAAkB,kBAClBC,EAAW,WACXC,EAAS,SACTC,EAAY,YACZC,EAAmCP,EAAeQ,QAAO,SAAUC,EAAKC,GACjF,OAAOD,EAAIE,OAAO,CAACD,EAAY,IAAMT,EAAOS,EAAY,IAAMR,GAChE,GAAG,IACQ,EAA0B,GAAGS,OAAOX,EAAgB,CAACD,IAAOS,QAAO,SAAUC,EAAKC,GAC3F,OAAOD,EAAIE,OAAO,CAACD,EAAWA,EAAY,IAAMT,EAAOS,EAAY,IAAMR,GAC3E,GAAG,IAEQU,EAAa,aACbC,EAAO,OACPC,EAAY,YAEZC,EAAa,aACbC,EAAO,OACPC,EAAY,YAEZC,EAAc,cACdC,EAAQ,QACRC,EAAa,aACbC,EAAiB,CAACT,EAAYC,EAAMC,EAAWC,EAAYC,EAAMC,EAAWC,EAAaC,EAAOC,GC9B5F,SAASE,EAAYC,GAClC,OAAOA,GAAWA,EAAQC,UAAY,IAAIC,cAAgB,IAC5D,CCFe,SAASC,EAAUC,GAChC,GAAY,MAARA,EACF,OAAOC,OAGT,GAAwB,oBAApBD,EAAKE,WAAkC,CACzC,IAAIC,EAAgBH,EAAKG,cACzB,OAAOA,GAAgBA,EAAcC,aAAwBH,MAC/D,CAEA,OAAOD,CACT,CCTA,SAASK,EAAUL,GAEjB,OAAOA,aADUD,EAAUC,GAAMM,SACIN,aAAgBM,OACvD,CAEA,SAASC,EAAcP,GAErB,OAAOA,aADUD,EAAUC,GAAMQ,aACIR,aAAgBQ,WACvD,CAEA,SAASC,EAAaT,GAEpB,MAA0B,oBAAfU,aAKJV,aADUD,EAAUC,GAAMU,YACIV,aAAgBU,WACvD,CCwDA,SACEC,KAAM,cACNC,SAAS,EACTC,MAAO,QACPC,GA5EF,SAAqBC,GACnB,IAAIC,EAAQD,EAAKC,MACjB3D,OAAO4D,KAAKD,EAAME,UAAUC,SAAQ,SAAUR,GAC5C,IAAIS,EAAQJ,EAAMK,OAAOV,IAAS,CAAC,EAC/BW,EAAaN,EAAMM,WAAWX,IAAS,CAAC,EACxCf,EAAUoB,EAAME,SAASP,GAExBJ,EAAcX,IAAaD,EAAYC,KAO5CvC,OAAOkE,OAAO3B,EAAQwB,MAAOA,GAC7B/D,OAAO4D,KAAKK,GAAYH,SAAQ,SAAUR,GACxC,IAAI3C,EAAQsD,EAAWX,IAET,IAAV3C,EACF4B,EAAQ4B,gBAAgBb,GAExBf,EAAQ6B,aAAad,GAAgB,IAAV3C,EAAiB,GAAKA,EAErD,IACF,GACF,EAoDE0D,OAlDF,SAAgBC,GACd,IAAIX,EAAQW,EAAMX,MACdY,EAAgB,CAClBlD,OAAQ,CACNmD,SAAUb,EAAMc,QAAQC,SACxB5D,KAAM,IACN6D,IAAK,IACLC,OAAQ,KAEVC,MAAO,CACLL,SAAU,YAEZlD,UAAW,CAAC,GASd,OAPAtB,OAAOkE,OAAOP,EAAME,SAASxC,OAAO0C,MAAOQ,EAAclD,QACzDsC,EAAMK,OAASO,EAEXZ,EAAME,SAASgB,OACjB7E,OAAOkE,OAAOP,EAAME,SAASgB,MAAMd,MAAOQ,EAAcM,OAGnD,WACL7E,OAAO4D,KAAKD,EAAME,UAAUC,SAAQ,SAAUR,GAC5C,IAAIf,EAAUoB,EAAME,SAASP,GACzBW,EAAaN,EAAMM,WAAWX,IAAS,CAAC,EAGxCS,EAFkB/D,OAAO4D,KAAKD,EAAMK,OAAOzD,eAAe+C,GAAQK,EAAMK,OAAOV,GAAQiB,EAAcjB,IAE7E9B,QAAO,SAAUuC,EAAOe,GAElD,OADAf,EAAMe,GAAY,GACXf,CACT,GAAG,CAAC,GAECb,EAAcX,IAAaD,EAAYC,KAI5CvC,OAAOkE,OAAO3B,EAAQwB,MAAOA,GAC7B/D,OAAO4D,KAAKK,GAAYH,SAAQ,SAAUiB,GACxCxC,EAAQ4B,gBAAgBY,EAC1B,IACF,GACF,CACF,EASEC,SAAU,CAAC,kBCjFE,SAASC,EAAiBvD,GACvC,OAAOA,EAAUwD,MAAM,KAAK,EAC9B,CCHO,IAAI,EAAMC,KAAKC,IACX,EAAMD,KAAKE,IACXC,EAAQH,KAAKG,MCFT,SAASC,IACtB,IAAIC,EAASC,UAAUC,cAEvB,OAAc,MAAVF,GAAkBA,EAAOG,QAAUC,MAAMC,QAAQL,EAAOG,QACnDH,EAAOG,OAAOG,KAAI,SAAUC,GACjC,OAAOA,EAAKC,MAAQ,IAAMD,EAAKE,OACjC,IAAGC,KAAK,KAGHT,UAAUU,SACnB,CCTe,SAASC,IACtB,OAAQ,iCAAiCC,KAAKd,IAChD,CCCe,SAASe,EAAsB/D,EAASgE,EAAcC,QAC9C,IAAjBD,IACFA,GAAe,QAGO,IAApBC,IACFA,GAAkB,GAGpB,IAAIC,EAAalE,EAAQ+D,wBACrBI,EAAS,EACTC,EAAS,EAETJ,GAAgBrD,EAAcX,KAChCmE,EAASnE,EAAQqE,YAAc,GAAItB,EAAMmB,EAAWI,OAAStE,EAAQqE,aAAmB,EACxFD,EAASpE,EAAQuE,aAAe,GAAIxB,EAAMmB,EAAWM,QAAUxE,EAAQuE,cAAoB,GAG7F,IACIE,GADOhE,EAAUT,GAAWG,EAAUH,GAAWK,QAC3BoE,eAEtBC,GAAoBb,KAAsBI,EAC1CU,GAAKT,EAAW3F,MAAQmG,GAAoBD,EAAiBA,EAAeG,WAAa,IAAMT,EAC/FU,GAAKX,EAAW9B,KAAOsC,GAAoBD,EAAiBA,EAAeK,UAAY,IAAMV,EAC7FE,EAAQJ,EAAWI,MAAQH,EAC3BK,EAASN,EAAWM,OAASJ,EACjC,MAAO,CACLE,MAAOA,EACPE,OAAQA,EACRpC,IAAKyC,EACLvG,MAAOqG,EAAIL,EACXjG,OAAQwG,EAAIL,EACZjG,KAAMoG,EACNA,EAAGA,EACHE,EAAGA,EAEP,CCrCe,SAASE,EAAc/E,GACpC,IAAIkE,EAAaH,EAAsB/D,GAGnCsE,EAAQtE,EAAQqE,YAChBG,EAASxE,EAAQuE,aAUrB,OARI3B,KAAKoC,IAAId,EAAWI,MAAQA,IAAU,IACxCA,EAAQJ,EAAWI,OAGjB1B,KAAKoC,IAAId,EAAWM,OAASA,IAAW,IAC1CA,EAASN,EAAWM,QAGf,CACLG,EAAG3E,EAAQ4E,WACXC,EAAG7E,EAAQ8E,UACXR,MAAOA,EACPE,OAAQA,EAEZ,CCvBe,SAASS,EAASC,EAAQC,GACvC,IAAIC,EAAWD,EAAME,aAAeF,EAAME,cAE1C,GAAIH,EAAOD,SAASE,GAClB,OAAO,EAEJ,GAAIC,GAAYvE,EAAauE,GAAW,CACzC,IAAIE,EAAOH,EAEX,EAAG,CACD,GAAIG,GAAQJ,EAAOK,WAAWD,GAC5B,OAAO,EAITA,EAAOA,EAAKE,YAAcF,EAAKG,IACjC,OAASH,EACX,CAGF,OAAO,CACT,CCrBe,SAAS,EAAiBtF,GACvC,OAAOG,EAAUH,GAAS0F,iBAAiB1F,EAC7C,CCFe,SAAS2F,EAAe3F,GACrC,MAAO,CAAC,QAAS,KAAM,MAAM4F,QAAQ7F,EAAYC,KAAa,CAChE,CCFe,SAAS6F,EAAmB7F,GAEzC,QAASS,EAAUT,GAAWA,EAAQO,cACtCP,EAAQ8F,WAAazF,OAAOyF,UAAUC,eACxC,CCFe,SAASC,EAAchG,GACpC,MAA6B,SAAzBD,EAAYC,GACPA,EAMPA,EAAQiG,cACRjG,EAAQwF,aACR3E,EAAab,GAAWA,EAAQyF,KAAO,OAEvCI,EAAmB7F,EAGvB,CCVA,SAASkG,EAAoBlG,GAC3B,OAAKW,EAAcX,IACoB,UAAvC,EAAiBA,GAASiC,SAInBjC,EAAQmG,aAHN,IAIX,CAwCe,SAASC,EAAgBpG,GAItC,IAHA,IAAIK,EAASF,EAAUH,GACnBmG,EAAeD,EAAoBlG,GAEhCmG,GAAgBR,EAAeQ,IAA6D,WAA5C,EAAiBA,GAAclE,UACpFkE,EAAeD,EAAoBC,GAGrC,OAAIA,IAA+C,SAA9BpG,EAAYoG,IAA0D,SAA9BpG,EAAYoG,IAAwE,WAA5C,EAAiBA,GAAclE,UAC3H5B,EAGF8F,GAhDT,SAA4BnG,GAC1B,IAAIqG,EAAY,WAAWvC,KAAKd,KAGhC,GAFW,WAAWc,KAAKd,MAEfrC,EAAcX,IAII,UAFX,EAAiBA,GAEnBiC,SACb,OAAO,KAIX,IAAIqE,EAAcN,EAAchG,GAMhC,IAJIa,EAAayF,KACfA,EAAcA,EAAYb,MAGrB9E,EAAc2F,IAAgB,CAAC,OAAQ,QAAQV,QAAQ7F,EAAYuG,IAAgB,GAAG,CAC3F,IAAIC,EAAM,EAAiBD,GAI3B,GAAsB,SAAlBC,EAAIC,WAA4C,SAApBD,EAAIE,aAA0C,UAAhBF,EAAIG,UAAiF,IAA1D,CAAC,YAAa,eAAed,QAAQW,EAAII,aAAsBN,GAAgC,WAAnBE,EAAII,YAA2BN,GAAaE,EAAIK,QAAyB,SAAfL,EAAIK,OACjO,OAAON,EAEPA,EAAcA,EAAYd,UAE9B,CAEA,OAAO,IACT,CAgByBqB,CAAmB7G,IAAYK,CACxD,CCpEe,SAASyG,EAAyB3H,GAC/C,MAAO,CAAC,MAAO,UAAUyG,QAAQzG,IAAc,EAAI,IAAM,GAC3D,CCDO,SAAS4H,EAAOjE,EAAK1E,EAAOyE,GACjC,OAAO,EAAQC,EAAK,EAAQ1E,EAAOyE,GACrC,CCFe,SAASmE,EAAmBC,GACzC,OAAOxJ,OAAOkE,OAAO,CAAC,ECDf,CACLS,IAAK,EACL9D,MAAO,EACPD,OAAQ,EACRE,KAAM,GDHuC0I,EACjD,CEHe,SAASC,EAAgB9I,EAAOiD,GAC7C,OAAOA,EAAKpC,QAAO,SAAUkI,EAAS5J,GAEpC,OADA4J,EAAQ5J,GAAOa,EACR+I,CACT,GAAG,CAAC,EACN,CC4EA,SACEpG,KAAM,QACNC,SAAS,EACTC,MAAO,OACPC,GApEF,SAAeC,GACb,IAAIiG,EAEAhG,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KACZmB,EAAUf,EAAKe,QACfmF,EAAejG,EAAME,SAASgB,MAC9BgF,EAAgBlG,EAAMmG,cAAcD,cACpCE,EAAgB9E,EAAiBtB,EAAMjC,WACvCsI,EAAOX,EAAyBU,GAEhCE,EADa,CAACnJ,EAAMD,GAAOsH,QAAQ4B,IAAkB,EAClC,SAAW,QAElC,GAAKH,GAAiBC,EAAtB,CAIA,IAAIL,EAxBgB,SAAyBU,EAASvG,GAItD,OAAO4F,EAAsC,iBAH7CW,EAA6B,mBAAZA,EAAyBA,EAAQlK,OAAOkE,OAAO,CAAC,EAAGP,EAAMwG,MAAO,CAC/EzI,UAAWiC,EAAMjC,aACbwI,GACkDA,EAAUT,EAAgBS,EAASlJ,GAC7F,CAmBsBoJ,CAAgB3F,EAAQyF,QAASvG,GACjD0G,EAAY/C,EAAcsC,GAC1BU,EAAmB,MAATN,EAAe,EAAMlJ,EAC/ByJ,EAAmB,MAATP,EAAepJ,EAASC,EAClC2J,EAAU7G,EAAMwG,MAAM7I,UAAU2I,GAAOtG,EAAMwG,MAAM7I,UAAU0I,GAAQH,EAAcG,GAAQrG,EAAMwG,MAAM9I,OAAO4I,GAC9GQ,EAAYZ,EAAcG,GAAQrG,EAAMwG,MAAM7I,UAAU0I,GACxDU,EAAoB/B,EAAgBiB,GACpCe,EAAaD,EAA6B,MAATV,EAAeU,EAAkBE,cAAgB,EAAIF,EAAkBG,aAAe,EAAI,EAC3HC,EAAoBN,EAAU,EAAIC,EAAY,EAG9CpF,EAAMmE,EAAcc,GACpBlF,EAAMuF,EAAaN,EAAUJ,GAAOT,EAAce,GAClDQ,EAASJ,EAAa,EAAIN,EAAUJ,GAAO,EAAIa,EAC/CE,EAAS1B,EAAOjE,EAAK0F,EAAQ3F,GAE7B6F,EAAWjB,EACfrG,EAAMmG,cAAcxG,KAASqG,EAAwB,CAAC,GAAyBsB,GAAYD,EAAQrB,EAAsBuB,aAAeF,EAASD,EAAQpB,EAnBzJ,CAoBF,EAkCEtF,OAhCF,SAAgBC,GACd,IAAIX,EAAQW,EAAMX,MAEdwH,EADU7G,EAAMG,QACWlC,QAC3BqH,OAAoC,IAArBuB,EAA8B,sBAAwBA,EAErD,MAAhBvB,IAKwB,iBAAjBA,IACTA,EAAejG,EAAME,SAASxC,OAAO+J,cAAcxB,MAOhDpC,EAAS7D,EAAME,SAASxC,OAAQuI,KAIrCjG,EAAME,SAASgB,MAAQ+E,EACzB,EASE5E,SAAU,CAAC,iBACXqG,iBAAkB,CAAC,oBCxFN,SAASC,EAAa5J,GACnC,OAAOA,EAAUwD,MAAM,KAAK,EAC9B,CCOA,IAAIqG,GAAa,CACf5G,IAAK,OACL9D,MAAO,OACPD,OAAQ,OACRE,KAAM,QAeD,SAAS0K,GAAYlH,GAC1B,IAAImH,EAEApK,EAASiD,EAAMjD,OACfqK,EAAapH,EAAMoH,WACnBhK,EAAY4C,EAAM5C,UAClBiK,EAAYrH,EAAMqH,UAClBC,EAAUtH,EAAMsH,QAChBpH,EAAWF,EAAME,SACjBqH,EAAkBvH,EAAMuH,gBACxBC,EAAWxH,EAAMwH,SACjBC,EAAezH,EAAMyH,aACrBC,EAAU1H,EAAM0H,QAChBC,EAAaL,EAAQ1E,EACrBA,OAAmB,IAAf+E,EAAwB,EAAIA,EAChCC,EAAaN,EAAQxE,EACrBA,OAAmB,IAAf8E,EAAwB,EAAIA,EAEhCC,EAAgC,mBAAjBJ,EAA8BA,EAAa,CAC5D7E,EAAGA,EACHE,IACG,CACHF,EAAGA,EACHE,GAGFF,EAAIiF,EAAMjF,EACVE,EAAI+E,EAAM/E,EACV,IAAIgF,EAAOR,EAAQrL,eAAe,KAC9B8L,EAAOT,EAAQrL,eAAe,KAC9B+L,EAAQxL,EACRyL,EAAQ,EACRC,EAAM5J,OAEV,GAAIkJ,EAAU,CACZ,IAAIpD,EAAeC,EAAgBtH,GAC/BoL,EAAa,eACbC,EAAY,cAEZhE,IAAiBhG,EAAUrB,IAGmB,WAA5C,EAFJqH,EAAeN,EAAmB/G,IAECmD,UAAsC,aAAbA,IAC1DiI,EAAa,eACbC,EAAY,gBAOZhL,IAAc,IAAQA,IAAcZ,GAAQY,IAAcb,IAAU8K,IAAczK,KACpFqL,EAAQ3L,EAGRwG,IAFc4E,GAAWtD,IAAiB8D,GAAOA,EAAIxF,eAAiBwF,EAAIxF,eAAeD,OACzF2B,EAAa+D,IACEf,EAAW3E,OAC1BK,GAAKyE,EAAkB,GAAK,GAG1BnK,IAAcZ,IAASY,IAAc,GAAOA,IAAcd,GAAW+K,IAAczK,KACrFoL,EAAQzL,EAGRqG,IAFc8E,GAAWtD,IAAiB8D,GAAOA,EAAIxF,eAAiBwF,EAAIxF,eAAeH,MACzF6B,EAAagE,IACEhB,EAAW7E,MAC1BK,GAAK2E,EAAkB,GAAK,EAEhC,CAEA,IAgBMc,EAhBFC,EAAe5M,OAAOkE,OAAO,CAC/BM,SAAUA,GACTsH,GAAYP,IAEXsB,GAAyB,IAAjBd,EAlFd,SAA2BrI,EAAM8I,GAC/B,IAAItF,EAAIxD,EAAKwD,EACTE,EAAI1D,EAAK0D,EACT0F,EAAMN,EAAIO,kBAAoB,EAClC,MAAO,CACL7F,EAAG5B,EAAM4B,EAAI4F,GAAOA,GAAO,EAC3B1F,EAAG9B,EAAM8B,EAAI0F,GAAOA,GAAO,EAE/B,CA0EsCE,CAAkB,CACpD9F,EAAGA,EACHE,GACC1E,EAAUrB,IAAW,CACtB6F,EAAGA,EACHE,GAMF,OAHAF,EAAI2F,EAAM3F,EACVE,EAAIyF,EAAMzF,EAENyE,EAGK7L,OAAOkE,OAAO,CAAC,EAAG0I,IAAeD,EAAiB,CAAC,GAAkBJ,GAASF,EAAO,IAAM,GAAIM,EAAeL,GAASF,EAAO,IAAM,GAAIO,EAAe5D,WAAayD,EAAIO,kBAAoB,IAAM,EAAI,aAAe7F,EAAI,OAASE,EAAI,MAAQ,eAAiBF,EAAI,OAASE,EAAI,SAAUuF,IAG5R3M,OAAOkE,OAAO,CAAC,EAAG0I,IAAenB,EAAkB,CAAC,GAAmBc,GAASF,EAAOjF,EAAI,KAAO,GAAIqE,EAAgBa,GAASF,EAAOlF,EAAI,KAAO,GAAIuE,EAAgB1C,UAAY,GAAI0C,GAC9L,CA4CA,UACEnI,KAAM,gBACNC,SAAS,EACTC,MAAO,cACPC,GA9CF,SAAuBwJ,GACrB,IAAItJ,EAAQsJ,EAAMtJ,MACdc,EAAUwI,EAAMxI,QAChByI,EAAwBzI,EAAQoH,gBAChCA,OAA4C,IAA1BqB,GAA0CA,EAC5DC,EAAoB1I,EAAQqH,SAC5BA,OAAiC,IAAtBqB,GAAsCA,EACjDC,EAAwB3I,EAAQsH,aAChCA,OAAyC,IAA1BqB,GAA0CA,EACzDR,EAAe,CACjBlL,UAAWuD,EAAiBtB,EAAMjC,WAClCiK,UAAWL,EAAa3H,EAAMjC,WAC9BL,OAAQsC,EAAME,SAASxC,OACvBqK,WAAY/H,EAAMwG,MAAM9I,OACxBwK,gBAAiBA,EACjBG,QAAoC,UAA3BrI,EAAMc,QAAQC,UAGgB,MAArCf,EAAMmG,cAAcD,gBACtBlG,EAAMK,OAAO3C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMK,OAAO3C,OAAQmK,GAAYxL,OAAOkE,OAAO,CAAC,EAAG0I,EAAc,CACvGhB,QAASjI,EAAMmG,cAAcD,cAC7BrF,SAAUb,EAAMc,QAAQC,SACxBoH,SAAUA,EACVC,aAAcA,OAIe,MAA7BpI,EAAMmG,cAAcjF,QACtBlB,EAAMK,OAAOa,MAAQ7E,OAAOkE,OAAO,CAAC,EAAGP,EAAMK,OAAOa,MAAO2G,GAAYxL,OAAOkE,OAAO,CAAC,EAAG0I,EAAc,CACrGhB,QAASjI,EAAMmG,cAAcjF,MAC7BL,SAAU,WACVsH,UAAU,EACVC,aAAcA,OAIlBpI,EAAMM,WAAW5C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMM,WAAW5C,OAAQ,CACnE,wBAAyBsC,EAAMjC,WAEnC,EAQE2L,KAAM,CAAC,GCrKT,IAAIC,GAAU,CACZA,SAAS,GAsCX,UACEhK,KAAM,iBACNC,SAAS,EACTC,MAAO,QACPC,GAAI,WAAe,EACnBY,OAxCF,SAAgBX,GACd,IAAIC,EAAQD,EAAKC,MACb4J,EAAW7J,EAAK6J,SAChB9I,EAAUf,EAAKe,QACf+I,EAAkB/I,EAAQgJ,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7CE,EAAkBjJ,EAAQkJ,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7C9K,EAASF,EAAUiB,EAAME,SAASxC,QAClCuM,EAAgB,GAAGjM,OAAOgC,EAAMiK,cAActM,UAAWqC,EAAMiK,cAAcvM,QAYjF,OAVIoM,GACFG,EAAc9J,SAAQ,SAAU+J,GAC9BA,EAAaC,iBAAiB,SAAUP,EAASQ,OAAQT,GAC3D,IAGEK,GACF/K,EAAOkL,iBAAiB,SAAUP,EAASQ,OAAQT,IAG9C,WACDG,GACFG,EAAc9J,SAAQ,SAAU+J,GAC9BA,EAAaG,oBAAoB,SAAUT,EAASQ,OAAQT,GAC9D,IAGEK,GACF/K,EAAOoL,oBAAoB,SAAUT,EAASQ,OAAQT,GAE1D,CACF,EASED,KAAM,CAAC,GC/CT,IAAIY,GAAO,CACTnN,KAAM,QACND,MAAO,OACPD,OAAQ,MACR+D,IAAK,UAEQ,SAASuJ,GAAqBxM,GAC3C,OAAOA,EAAUyM,QAAQ,0BAA0B,SAAUC,GAC3D,OAAOH,GAAKG,EACd,GACF,CCVA,IAAI,GAAO,CACTnN,MAAO,MACPC,IAAK,SAEQ,SAASmN,GAA8B3M,GACpD,OAAOA,EAAUyM,QAAQ,cAAc,SAAUC,GAC/C,OAAO,GAAKA,EACd,GACF,CCPe,SAASE,GAAgB3L,GACtC,IAAI6J,EAAM9J,EAAUC,GAGpB,MAAO,CACL4L,WAHe/B,EAAIgC,YAInBC,UAHcjC,EAAIkC,YAKtB,CCNe,SAASC,GAAoBpM,GAQ1C,OAAO+D,EAAsB8B,EAAmB7F,IAAUzB,KAAOwN,GAAgB/L,GAASgM,UAC5F,CCXe,SAASK,GAAerM,GAErC,IAAIsM,EAAoB,EAAiBtM,GACrCuM,EAAWD,EAAkBC,SAC7BC,EAAYF,EAAkBE,UAC9BC,EAAYH,EAAkBG,UAElC,MAAO,6BAA6B3I,KAAKyI,EAAWE,EAAYD,EAClE,CCLe,SAASE,GAAgBtM,GACtC,MAAI,CAAC,OAAQ,OAAQ,aAAawF,QAAQ7F,EAAYK,KAAU,EAEvDA,EAAKG,cAAcoM,KAGxBhM,EAAcP,IAASiM,GAAejM,GACjCA,EAGFsM,GAAgB1G,EAAc5F,GACvC,CCJe,SAASwM,GAAkB5M,EAAS6M,GACjD,IAAIC,OAES,IAATD,IACFA,EAAO,IAGT,IAAIvB,EAAeoB,GAAgB1M,GAC/B+M,EAASzB,KAAqE,OAAlDwB,EAAwB9M,EAAQO,oBAAyB,EAASuM,EAAsBH,MACpH1C,EAAM9J,EAAUmL,GAChB0B,EAASD,EAAS,CAAC9C,GAAK7K,OAAO6K,EAAIxF,gBAAkB,GAAI4H,GAAef,GAAgBA,EAAe,IAAMA,EAC7G2B,EAAcJ,EAAKzN,OAAO4N,GAC9B,OAAOD,EAASE,EAChBA,EAAY7N,OAAOwN,GAAkB5G,EAAcgH,IACrD,CCzBe,SAASE,GAAiBC,GACvC,OAAO1P,OAAOkE,OAAO,CAAC,EAAGwL,EAAM,CAC7B5O,KAAM4O,EAAKxI,EACXvC,IAAK+K,EAAKtI,EACVvG,MAAO6O,EAAKxI,EAAIwI,EAAK7I,MACrBjG,OAAQ8O,EAAKtI,EAAIsI,EAAK3I,QAE1B,CCqBA,SAAS4I,GAA2BpN,EAASqN,EAAgBlL,GAC3D,OAAOkL,IAAmBxO,EAAWqO,GCzBxB,SAAyBlN,EAASmC,GAC/C,IAAI8H,EAAM9J,EAAUH,GAChBsN,EAAOzH,EAAmB7F,GAC1ByE,EAAiBwF,EAAIxF,eACrBH,EAAQgJ,EAAKhF,YACb9D,EAAS8I,EAAKjF,aACd1D,EAAI,EACJE,EAAI,EAER,GAAIJ,EAAgB,CAClBH,EAAQG,EAAeH,MACvBE,EAASC,EAAeD,OACxB,IAAI+I,EAAiB1J,KAEjB0J,IAAmBA,GAA+B,UAAbpL,KACvCwC,EAAIF,EAAeG,WACnBC,EAAIJ,EAAeK,UAEvB,CAEA,MAAO,CACLR,MAAOA,EACPE,OAAQA,EACRG,EAAGA,EAAIyH,GAAoBpM,GAC3B6E,EAAGA,EAEP,CDDwD2I,CAAgBxN,EAASmC,IAAa1B,EAAU4M,GAdxG,SAAoCrN,EAASmC,GAC3C,IAAIgL,EAAOpJ,EAAsB/D,GAAS,EAAoB,UAAbmC,GASjD,OARAgL,EAAK/K,IAAM+K,EAAK/K,IAAMpC,EAAQyN,UAC9BN,EAAK5O,KAAO4O,EAAK5O,KAAOyB,EAAQ0N,WAChCP,EAAK9O,OAAS8O,EAAK/K,IAAMpC,EAAQqI,aACjC8E,EAAK7O,MAAQ6O,EAAK5O,KAAOyB,EAAQsI,YACjC6E,EAAK7I,MAAQtE,EAAQsI,YACrB6E,EAAK3I,OAASxE,EAAQqI,aACtB8E,EAAKxI,EAAIwI,EAAK5O,KACd4O,EAAKtI,EAAIsI,EAAK/K,IACP+K,CACT,CAG0HQ,CAA2BN,EAAgBlL,GAAY+K,GEtBlK,SAAyBlN,GACtC,IAAI8M,EAEAQ,EAAOzH,EAAmB7F,GAC1B4N,EAAY7B,GAAgB/L,GAC5B2M,EAA0D,OAAlDG,EAAwB9M,EAAQO,oBAAyB,EAASuM,EAAsBH,KAChGrI,EAAQ,EAAIgJ,EAAKO,YAAaP,EAAKhF,YAAaqE,EAAOA,EAAKkB,YAAc,EAAGlB,EAAOA,EAAKrE,YAAc,GACvG9D,EAAS,EAAI8I,EAAKQ,aAAcR,EAAKjF,aAAcsE,EAAOA,EAAKmB,aAAe,EAAGnB,EAAOA,EAAKtE,aAAe,GAC5G1D,GAAKiJ,EAAU5B,WAAaI,GAAoBpM,GAChD6E,GAAK+I,EAAU1B,UAMnB,MAJiD,QAA7C,EAAiBS,GAAQW,GAAMS,YACjCpJ,GAAK,EAAI2I,EAAKhF,YAAaqE,EAAOA,EAAKrE,YAAc,GAAKhE,GAGrD,CACLA,MAAOA,EACPE,OAAQA,EACRG,EAAGA,EACHE,EAAGA,EAEP,CFCkMmJ,CAAgBnI,EAAmB7F,IACrO,CG1Be,SAASiO,GAAe9M,GACrC,IAOIkI,EAPAtK,EAAYoC,EAAKpC,UACjBiB,EAAUmB,EAAKnB,QACfb,EAAYgC,EAAKhC,UACjBqI,EAAgBrI,EAAYuD,EAAiBvD,GAAa,KAC1DiK,EAAYjK,EAAY4J,EAAa5J,GAAa,KAClD+O,EAAUnP,EAAU4F,EAAI5F,EAAUuF,MAAQ,EAAItE,EAAQsE,MAAQ,EAC9D6J,EAAUpP,EAAU8F,EAAI9F,EAAUyF,OAAS,EAAIxE,EAAQwE,OAAS,EAGpE,OAAQgD,GACN,KAAK,EACH6B,EAAU,CACR1E,EAAGuJ,EACHrJ,EAAG9F,EAAU8F,EAAI7E,EAAQwE,QAE3B,MAEF,KAAKnG,EACHgL,EAAU,CACR1E,EAAGuJ,EACHrJ,EAAG9F,EAAU8F,EAAI9F,EAAUyF,QAE7B,MAEF,KAAKlG,EACH+K,EAAU,CACR1E,EAAG5F,EAAU4F,EAAI5F,EAAUuF,MAC3BO,EAAGsJ,GAEL,MAEF,KAAK5P,EACH8K,EAAU,CACR1E,EAAG5F,EAAU4F,EAAI3E,EAAQsE,MACzBO,EAAGsJ,GAEL,MAEF,QACE9E,EAAU,CACR1E,EAAG5F,EAAU4F,EACbE,EAAG9F,EAAU8F,GAInB,IAAIuJ,EAAW5G,EAAgBV,EAAyBU,GAAiB,KAEzE,GAAgB,MAAZ4G,EAAkB,CACpB,IAAI1G,EAAmB,MAAb0G,EAAmB,SAAW,QAExC,OAAQhF,GACN,KAAK1K,EACH2K,EAAQ+E,GAAY/E,EAAQ+E,IAAarP,EAAU2I,GAAO,EAAI1H,EAAQ0H,GAAO,GAC7E,MAEF,KAAK/I,EACH0K,EAAQ+E,GAAY/E,EAAQ+E,IAAarP,EAAU2I,GAAO,EAAI1H,EAAQ0H,GAAO,GAKnF,CAEA,OAAO2B,CACT,CC3De,SAASgF,GAAejN,EAAOc,QAC5B,IAAZA,IACFA,EAAU,CAAC,GAGb,IAAIoM,EAAWpM,EACXqM,EAAqBD,EAASnP,UAC9BA,OAAmC,IAAvBoP,EAAgCnN,EAAMjC,UAAYoP,EAC9DC,EAAoBF,EAASnM,SAC7BA,OAAiC,IAAtBqM,EAA+BpN,EAAMe,SAAWqM,EAC3DC,EAAoBH,EAASI,SAC7BA,OAAiC,IAAtBD,EAA+B7P,EAAkB6P,EAC5DE,EAAwBL,EAASM,aACjCA,OAAyC,IAA1BD,EAAmC9P,EAAW8P,EAC7DE,EAAwBP,EAASQ,eACjCA,OAA2C,IAA1BD,EAAmC/P,EAAS+P,EAC7DE,EAAuBT,EAASU,YAChCA,OAAuC,IAAzBD,GAA0CA,EACxDE,EAAmBX,EAAS3G,QAC5BA,OAA+B,IAArBsH,EAA8B,EAAIA,EAC5ChI,EAAgBD,EAAsC,iBAAZW,EAAuBA,EAAUT,EAAgBS,EAASlJ,IACpGyQ,EAAaJ,IAAmBhQ,EAASC,EAAYD,EACrDqK,EAAa/H,EAAMwG,MAAM9I,OACzBkB,EAAUoB,EAAME,SAAS0N,EAAcE,EAAaJ,GACpDK,EJkBS,SAAyBnP,EAAS0O,EAAUE,EAAczM,GACvE,IAAIiN,EAAmC,oBAAbV,EAlB5B,SAA4B1O,GAC1B,IAAIpB,EAAkBgO,GAAkB5G,EAAchG,IAElDqP,EADoB,CAAC,WAAY,SAASzJ,QAAQ,EAAiB5F,GAASiC,WAAa,GACnDtB,EAAcX,GAAWoG,EAAgBpG,GAAWA,EAE9F,OAAKS,EAAU4O,GAKRzQ,EAAgBgI,QAAO,SAAUyG,GACtC,OAAO5M,EAAU4M,IAAmBpI,EAASoI,EAAgBgC,IAAmD,SAAhCtP,EAAYsN,EAC9F,IANS,EAOX,CAK6DiC,CAAmBtP,GAAW,GAAGZ,OAAOsP,GAC/F9P,EAAkB,GAAGQ,OAAOgQ,EAAqB,CAACR,IAClDW,EAAsB3Q,EAAgB,GACtC4Q,EAAe5Q,EAAgBK,QAAO,SAAUwQ,EAASpC,GAC3D,IAAIF,EAAOC,GAA2BpN,EAASqN,EAAgBlL,GAK/D,OAJAsN,EAAQrN,IAAM,EAAI+K,EAAK/K,IAAKqN,EAAQrN,KACpCqN,EAAQnR,MAAQ,EAAI6O,EAAK7O,MAAOmR,EAAQnR,OACxCmR,EAAQpR,OAAS,EAAI8O,EAAK9O,OAAQoR,EAAQpR,QAC1CoR,EAAQlR,KAAO,EAAI4O,EAAK5O,KAAMkR,EAAQlR,MAC/BkR,CACT,GAAGrC,GAA2BpN,EAASuP,EAAqBpN,IAK5D,OAJAqN,EAAalL,MAAQkL,EAAalR,MAAQkR,EAAajR,KACvDiR,EAAahL,OAASgL,EAAanR,OAASmR,EAAapN,IACzDoN,EAAa7K,EAAI6K,EAAajR,KAC9BiR,EAAa3K,EAAI2K,EAAapN,IACvBoN,CACT,CInC2BE,CAAgBjP,EAAUT,GAAWA,EAAUA,EAAQ2P,gBAAkB9J,EAAmBzE,EAAME,SAASxC,QAAS4P,EAAUE,EAAczM,GACjKyN,EAAsB7L,EAAsB3C,EAAME,SAASvC,WAC3DuI,EAAgB2G,GAAe,CACjClP,UAAW6Q,EACX5P,QAASmJ,EACThH,SAAU,WACVhD,UAAWA,IAET0Q,EAAmB3C,GAAiBzP,OAAOkE,OAAO,CAAC,EAAGwH,EAAY7B,IAClEwI,EAAoBhB,IAAmBhQ,EAAS+Q,EAAmBD,EAGnEG,EAAkB,CACpB3N,IAAK+M,EAAmB/M,IAAM0N,EAAkB1N,IAAM6E,EAAc7E,IACpE/D,OAAQyR,EAAkBzR,OAAS8Q,EAAmB9Q,OAAS4I,EAAc5I,OAC7EE,KAAM4Q,EAAmB5Q,KAAOuR,EAAkBvR,KAAO0I,EAAc1I,KACvED,MAAOwR,EAAkBxR,MAAQ6Q,EAAmB7Q,MAAQ2I,EAAc3I,OAExE0R,EAAa5O,EAAMmG,cAAckB,OAErC,GAAIqG,IAAmBhQ,GAAUkR,EAAY,CAC3C,IAAIvH,EAASuH,EAAW7Q,GACxB1B,OAAO4D,KAAK0O,GAAiBxO,SAAQ,SAAUhE,GAC7C,IAAI0S,EAAW,CAAC3R,EAAOD,GAAQuH,QAAQrI,IAAQ,EAAI,GAAK,EACpDkK,EAAO,CAAC,EAAKpJ,GAAQuH,QAAQrI,IAAQ,EAAI,IAAM,IACnDwS,EAAgBxS,IAAQkL,EAAOhB,GAAQwI,CACzC,GACF,CAEA,OAAOF,CACT,CCyEA,UACEhP,KAAM,OACNC,SAAS,EACTC,MAAO,OACPC,GA5HF,SAAcC,GACZ,IAAIC,EAAQD,EAAKC,MACbc,EAAUf,EAAKe,QACfnB,EAAOI,EAAKJ,KAEhB,IAAIK,EAAMmG,cAAcxG,GAAMmP,MAA9B,CAoCA,IAhCA,IAAIC,EAAoBjO,EAAQkM,SAC5BgC,OAAsC,IAAtBD,GAAsCA,EACtDE,EAAmBnO,EAAQoO,QAC3BC,OAAoC,IAArBF,GAAqCA,EACpDG,EAA8BtO,EAAQuO,mBACtC9I,EAAUzF,EAAQyF,QAClB+G,EAAWxM,EAAQwM,SACnBE,EAAe1M,EAAQ0M,aACvBI,EAAc9M,EAAQ8M,YACtB0B,EAAwBxO,EAAQyO,eAChCA,OAA2C,IAA1BD,GAA0CA,EAC3DE,EAAwB1O,EAAQ0O,sBAChCC,EAAqBzP,EAAMc,QAAQ/C,UACnCqI,EAAgB9E,EAAiBmO,GAEjCJ,EAAqBD,IADHhJ,IAAkBqJ,GACqCF,EAjC/E,SAAuCxR,GACrC,GAAIuD,EAAiBvD,KAAeX,EAClC,MAAO,GAGT,IAAIsS,EAAoBnF,GAAqBxM,GAC7C,MAAO,CAAC2M,GAA8B3M,GAAY2R,EAAmBhF,GAA8BgF,GACrG,CA0B6IC,CAA8BF,GAA3E,CAAClF,GAAqBkF,KAChHG,EAAa,CAACH,GAAoBzR,OAAOqR,GAAoBxR,QAAO,SAAUC,EAAKC,GACrF,OAAOD,EAAIE,OAAOsD,EAAiBvD,KAAeX,ECvCvC,SAA8B4C,EAAOc,QAClC,IAAZA,IACFA,EAAU,CAAC,GAGb,IAAIoM,EAAWpM,EACX/C,EAAYmP,EAASnP,UACrBuP,EAAWJ,EAASI,SACpBE,EAAeN,EAASM,aACxBjH,EAAU2G,EAAS3G,QACnBgJ,EAAiBrC,EAASqC,eAC1BM,EAAwB3C,EAASsC,sBACjCA,OAAkD,IAA1BK,EAAmC,EAAgBA,EAC3E7H,EAAYL,EAAa5J,GACzB6R,EAAa5H,EAAYuH,EAAiB3R,EAAsBA,EAAoB4H,QAAO,SAAUzH,GACvG,OAAO4J,EAAa5J,KAAeiK,CACrC,IAAK3K,EACDyS,EAAoBF,EAAWpK,QAAO,SAAUzH,GAClD,OAAOyR,EAAsBhL,QAAQzG,IAAc,CACrD,IAEiC,IAA7B+R,EAAkBC,SACpBD,EAAoBF,GAItB,IAAII,EAAYF,EAAkBjS,QAAO,SAAUC,EAAKC,GAOtD,OANAD,EAAIC,GAAakP,GAAejN,EAAO,CACrCjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdjH,QAASA,IACRjF,EAAiBvD,IACbD,CACT,GAAG,CAAC,GACJ,OAAOzB,OAAO4D,KAAK+P,GAAWC,MAAK,SAAUC,EAAGC,GAC9C,OAAOH,EAAUE,GAAKF,EAAUG,EAClC,GACF,CDC6DC,CAAqBpQ,EAAO,CACnFjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdjH,QAASA,EACTgJ,eAAgBA,EAChBC,sBAAuBA,IACpBzR,EACP,GAAG,IACCsS,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzB4S,EAAY,IAAIC,IAChBC,GAAqB,EACrBC,EAAwBb,EAAW,GAE9Bc,EAAI,EAAGA,EAAId,EAAWG,OAAQW,IAAK,CAC1C,IAAI3S,EAAY6R,EAAWc,GAEvBC,EAAiBrP,EAAiBvD,GAElC6S,EAAmBjJ,EAAa5J,KAAeT,EAC/CuT,EAAa,CAAC,EAAK5T,GAAQuH,QAAQmM,IAAmB,EACtDrK,EAAMuK,EAAa,QAAU,SAC7B1F,EAAW8B,GAAejN,EAAO,CACnCjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdI,YAAaA,EACbrH,QAASA,IAEPuK,EAAoBD,EAAaD,EAAmB1T,EAAQC,EAAOyT,EAAmB3T,EAAS,EAE/FoT,EAAc/J,GAAOyB,EAAWzB,KAClCwK,EAAoBvG,GAAqBuG,IAG3C,IAAIC,EAAmBxG,GAAqBuG,GACxCE,EAAS,GAUb,GARIhC,GACFgC,EAAOC,KAAK9F,EAASwF,IAAmB,GAGtCxB,GACF6B,EAAOC,KAAK9F,EAAS2F,IAAsB,EAAG3F,EAAS4F,IAAqB,GAG1EC,EAAOE,OAAM,SAAUC,GACzB,OAAOA,CACT,IAAI,CACFV,EAAwB1S,EACxByS,GAAqB,EACrB,KACF,CAEAF,EAAUc,IAAIrT,EAAWiT,EAC3B,CAEA,GAAIR,EAqBF,IAnBA,IAEIa,EAAQ,SAAeC,GACzB,IAAIC,EAAmB3B,EAAW4B,MAAK,SAAUzT,GAC/C,IAAIiT,EAASV,EAAU9T,IAAIuB,GAE3B,GAAIiT,EACF,OAAOA,EAAOS,MAAM,EAAGH,GAAIJ,OAAM,SAAUC,GACzC,OAAOA,CACT,GAEJ,IAEA,GAAII,EAEF,OADAd,EAAwBc,EACjB,OAEX,EAESD,EAnBY/B,EAAiB,EAAI,EAmBZ+B,EAAK,GAGpB,UAFFD,EAAMC,GADmBA,KAOpCtR,EAAMjC,YAAc0S,IACtBzQ,EAAMmG,cAAcxG,GAAMmP,OAAQ,EAClC9O,EAAMjC,UAAY0S,EAClBzQ,EAAM0R,OAAQ,EA5GhB,CA8GF,EAQEhK,iBAAkB,CAAC,UACnBgC,KAAM,CACJoF,OAAO,IE7IX,SAAS6C,GAAexG,EAAUY,EAAM6F,GAQtC,YAPyB,IAArBA,IACFA,EAAmB,CACjBrO,EAAG,EACHE,EAAG,IAIA,CACLzC,IAAKmK,EAASnK,IAAM+K,EAAK3I,OAASwO,EAAiBnO,EACnDvG,MAAOiO,EAASjO,MAAQ6O,EAAK7I,MAAQ0O,EAAiBrO,EACtDtG,OAAQkO,EAASlO,OAAS8O,EAAK3I,OAASwO,EAAiBnO,EACzDtG,KAAMgO,EAAShO,KAAO4O,EAAK7I,MAAQ0O,EAAiBrO,EAExD,CAEA,SAASsO,GAAsB1G,GAC7B,MAAO,CAAC,EAAKjO,EAAOD,EAAQE,GAAM2U,MAAK,SAAUC,GAC/C,OAAO5G,EAAS4G,IAAS,CAC3B,GACF,CA+BA,UACEpS,KAAM,OACNC,SAAS,EACTC,MAAO,OACP6H,iBAAkB,CAAC,mBACnB5H,GAlCF,SAAcC,GACZ,IAAIC,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KACZ0Q,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzBkU,EAAmB5R,EAAMmG,cAAc6L,gBACvCC,EAAoBhF,GAAejN,EAAO,CAC5C0N,eAAgB,cAEdwE,EAAoBjF,GAAejN,EAAO,CAC5C4N,aAAa,IAEXuE,EAA2BR,GAAeM,EAAmB5B,GAC7D+B,EAAsBT,GAAeO,EAAmBnK,EAAY6J,GACpES,EAAoBR,GAAsBM,GAC1CG,EAAmBT,GAAsBO,GAC7CpS,EAAMmG,cAAcxG,GAAQ,CAC1BwS,yBAA0BA,EAC1BC,oBAAqBA,EACrBC,kBAAmBA,EACnBC,iBAAkBA,GAEpBtS,EAAMM,WAAW5C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMM,WAAW5C,OAAQ,CACnE,+BAAgC2U,EAChC,sBAAuBC,GAE3B,GCJA,IACE3S,KAAM,SACNC,SAAS,EACTC,MAAO,OACPwB,SAAU,CAAC,iBACXvB,GA5BF,SAAgBa,GACd,IAAIX,EAAQW,EAAMX,MACdc,EAAUH,EAAMG,QAChBnB,EAAOgB,EAAMhB,KACb4S,EAAkBzR,EAAQuG,OAC1BA,OAA6B,IAApBkL,EAA6B,CAAC,EAAG,GAAKA,EAC/C7I,EAAO,EAAW7L,QAAO,SAAUC,EAAKC,GAE1C,OADAD,EAAIC,GA5BD,SAAiCA,EAAWyI,EAAOa,GACxD,IAAIjB,EAAgB9E,EAAiBvD,GACjCyU,EAAiB,CAACrV,EAAM,GAAKqH,QAAQ4B,IAAkB,GAAK,EAAI,EAEhErG,EAAyB,mBAAXsH,EAAwBA,EAAOhL,OAAOkE,OAAO,CAAC,EAAGiG,EAAO,CACxEzI,UAAWA,KACPsJ,EACFoL,EAAW1S,EAAK,GAChB2S,EAAW3S,EAAK,GAIpB,OAFA0S,EAAWA,GAAY,EACvBC,GAAYA,GAAY,GAAKF,EACtB,CAACrV,EAAMD,GAAOsH,QAAQ4B,IAAkB,EAAI,CACjD7C,EAAGmP,EACHjP,EAAGgP,GACD,CACFlP,EAAGkP,EACHhP,EAAGiP,EAEP,CASqBC,CAAwB5U,EAAWiC,EAAMwG,MAAOa,GAC1DvJ,CACT,GAAG,CAAC,GACA8U,EAAwBlJ,EAAK1J,EAAMjC,WACnCwF,EAAIqP,EAAsBrP,EAC1BE,EAAImP,EAAsBnP,EAEW,MAArCzD,EAAMmG,cAAcD,gBACtBlG,EAAMmG,cAAcD,cAAc3C,GAAKA,EACvCvD,EAAMmG,cAAcD,cAAczC,GAAKA,GAGzCzD,EAAMmG,cAAcxG,GAAQ+J,CAC9B,GC1BA,IACE/J,KAAM,gBACNC,SAAS,EACTC,MAAO,OACPC,GApBF,SAAuBC,GACrB,IAAIC,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KAKhBK,EAAMmG,cAAcxG,GAAQkN,GAAe,CACzClP,UAAWqC,EAAMwG,MAAM7I,UACvBiB,QAASoB,EAAMwG,MAAM9I,OACrBqD,SAAU,WACVhD,UAAWiC,EAAMjC,WAErB,EAQE2L,KAAM,CAAC,GCgHT,IACE/J,KAAM,kBACNC,SAAS,EACTC,MAAO,OACPC,GA/HF,SAAyBC,GACvB,IAAIC,EAAQD,EAAKC,MACbc,EAAUf,EAAKe,QACfnB,EAAOI,EAAKJ,KACZoP,EAAoBjO,EAAQkM,SAC5BgC,OAAsC,IAAtBD,GAAsCA,EACtDE,EAAmBnO,EAAQoO,QAC3BC,OAAoC,IAArBF,GAAsCA,EACrD3B,EAAWxM,EAAQwM,SACnBE,EAAe1M,EAAQ0M,aACvBI,EAAc9M,EAAQ8M,YACtBrH,EAAUzF,EAAQyF,QAClBsM,EAAkB/R,EAAQgS,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7CE,EAAwBjS,EAAQkS,aAChCA,OAAyC,IAA1BD,EAAmC,EAAIA,EACtD5H,EAAW8B,GAAejN,EAAO,CACnCsN,SAAUA,EACVE,aAAcA,EACdjH,QAASA,EACTqH,YAAaA,IAEXxH,EAAgB9E,EAAiBtB,EAAMjC,WACvCiK,EAAYL,EAAa3H,EAAMjC,WAC/BkV,GAAmBjL,EACnBgF,EAAWtH,EAAyBU,GACpC8I,ECrCY,MDqCSlC,ECrCH,IAAM,IDsCxB9G,EAAgBlG,EAAMmG,cAAcD,cACpCmK,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzBwV,EAA4C,mBAAjBF,EAA8BA,EAAa3W,OAAOkE,OAAO,CAAC,EAAGP,EAAMwG,MAAO,CACvGzI,UAAWiC,EAAMjC,aACbiV,EACFG,EAA2D,iBAAtBD,EAAiC,CACxElG,SAAUkG,EACVhE,QAASgE,GACP7W,OAAOkE,OAAO,CAChByM,SAAU,EACVkC,QAAS,GACRgE,GACCE,EAAsBpT,EAAMmG,cAAckB,OAASrH,EAAMmG,cAAckB,OAAOrH,EAAMjC,WAAa,KACjG2L,EAAO,CACTnG,EAAG,EACHE,EAAG,GAGL,GAAKyC,EAAL,CAIA,GAAI8I,EAAe,CACjB,IAAIqE,EAEAC,EAAwB,MAAbtG,EAAmB,EAAM7P,EACpCoW,EAAuB,MAAbvG,EAAmB/P,EAASC,EACtCoJ,EAAmB,MAAb0G,EAAmB,SAAW,QACpC3F,EAASnB,EAAc8G,GACvBtL,EAAM2F,EAAS8D,EAASmI,GACxB7R,EAAM4F,EAAS8D,EAASoI,GACxBC,EAAWV,GAAU/K,EAAWzB,GAAO,EAAI,EAC3CmN,EAASzL,IAAc1K,EAAQ+S,EAAc/J,GAAOyB,EAAWzB,GAC/DoN,EAAS1L,IAAc1K,GAASyK,EAAWzB,IAAQ+J,EAAc/J,GAGjEL,EAAejG,EAAME,SAASgB,MAC9BwF,EAAYoM,GAAU7M,EAAetC,EAAcsC,GAAgB,CACrE/C,MAAO,EACPE,OAAQ,GAENuQ,GAAqB3T,EAAMmG,cAAc,oBAAsBnG,EAAMmG,cAAc,oBAAoBI,QxBhFtG,CACLvF,IAAK,EACL9D,MAAO,EACPD,OAAQ,EACRE,KAAM,GwB6EFyW,GAAkBD,GAAmBL,GACrCO,GAAkBF,GAAmBJ,GAMrCO,GAAWnO,EAAO,EAAG0K,EAAc/J,GAAMI,EAAUJ,IACnDyN,GAAYd,EAAkB5C,EAAc/J,GAAO,EAAIkN,EAAWM,GAAWF,GAAkBT,EAA4BnG,SAAWyG,EAASK,GAAWF,GAAkBT,EAA4BnG,SACxMgH,GAAYf,GAAmB5C,EAAc/J,GAAO,EAAIkN,EAAWM,GAAWD,GAAkBV,EAA4BnG,SAAW0G,EAASI,GAAWD,GAAkBV,EAA4BnG,SACzMjG,GAAoB/G,EAAME,SAASgB,OAAS8D,EAAgBhF,EAAME,SAASgB,OAC3E+S,GAAelN,GAAiC,MAAbiG,EAAmBjG,GAAkBsF,WAAa,EAAItF,GAAkBuF,YAAc,EAAI,EAC7H4H,GAAwH,OAAjGb,EAA+C,MAAvBD,OAA8B,EAASA,EAAoBpG,IAAqBqG,EAAwB,EAEvJc,GAAY9M,EAAS2M,GAAYE,GACjCE,GAAkBzO,EAAOmN,EAAS,EAAQpR,EAF9B2F,EAAS0M,GAAYG,GAAsBD,IAEKvS,EAAK2F,EAAQyL,EAAS,EAAQrR,EAAK0S,IAAa1S,GAChHyE,EAAc8G,GAAYoH,GAC1B1K,EAAKsD,GAAYoH,GAAkB/M,CACrC,CAEA,GAAI8H,EAAc,CAChB,IAAIkF,GAEAC,GAAyB,MAAbtH,EAAmB,EAAM7P,EAErCoX,GAAwB,MAAbvH,EAAmB/P,EAASC,EAEvCsX,GAAUtO,EAAcgJ,GAExBuF,GAAmB,MAAZvF,EAAkB,SAAW,QAEpCwF,GAAOF,GAAUrJ,EAASmJ,IAE1BK,GAAOH,GAAUrJ,EAASoJ,IAE1BK,IAAuD,IAAxC,CAAC,EAAKzX,GAAMqH,QAAQ4B,GAEnCyO,GAAyH,OAAjGR,GAAgD,MAAvBjB,OAA8B,EAASA,EAAoBlE,IAAoBmF,GAAyB,EAEzJS,GAAaF,GAAeF,GAAOF,GAAUnE,EAAcoE,IAAQ1M,EAAW0M,IAAQI,GAAuB1B,EAA4BjE,QAEzI6F,GAAaH,GAAeJ,GAAUnE,EAAcoE,IAAQ1M,EAAW0M,IAAQI,GAAuB1B,EAA4BjE,QAAUyF,GAE5IK,GAAmBlC,GAAU8B,G1BzH9B,SAAwBlT,EAAK1E,EAAOyE,GACzC,IAAIwT,EAAItP,EAAOjE,EAAK1E,EAAOyE,GAC3B,OAAOwT,EAAIxT,EAAMA,EAAMwT,CACzB,C0BsHoDC,CAAeJ,GAAYN,GAASO,IAAcpP,EAAOmN,EAASgC,GAAaJ,GAAMF,GAAS1B,EAASiC,GAAaJ,IAEpKzO,EAAcgJ,GAAW8F,GACzBtL,EAAKwF,GAAW8F,GAAmBR,EACrC,CAEAxU,EAAMmG,cAAcxG,GAAQ+J,CAvE5B,CAwEF,EAQEhC,iBAAkB,CAAC,WE1HN,SAASyN,GAAiBC,EAAyBrQ,EAAcsD,QAC9D,IAAZA,IACFA,GAAU,GAGZ,ICnBoCrJ,ECJOJ,EFuBvCyW,EAA0B9V,EAAcwF,GACxCuQ,EAAuB/V,EAAcwF,IAf3C,SAAyBnG,GACvB,IAAImN,EAAOnN,EAAQ+D,wBACfI,EAASpB,EAAMoK,EAAK7I,OAAStE,EAAQqE,aAAe,EACpDD,EAASrB,EAAMoK,EAAK3I,QAAUxE,EAAQuE,cAAgB,EAC1D,OAAkB,IAAXJ,GAA2B,IAAXC,CACzB,CAU4DuS,CAAgBxQ,GACtEJ,EAAkBF,EAAmBM,GACrCgH,EAAOpJ,EAAsByS,EAAyBE,EAAsBjN,GAC5EyB,EAAS,CACXc,WAAY,EACZE,UAAW,GAET7C,EAAU,CACZ1E,EAAG,EACHE,EAAG,GAkBL,OAfI4R,IAA4BA,IAA4BhN,MACxB,SAA9B1J,EAAYoG,IAChBkG,GAAetG,MACbmF,GCnCgC9K,EDmCT+F,KClCdhG,EAAUC,IAAUO,EAAcP,GCJxC,CACL4L,YAFyChM,EDQbI,GCNR4L,WACpBE,UAAWlM,EAAQkM,WDGZH,GAAgB3L,IDoCnBO,EAAcwF,KAChBkD,EAAUtF,EAAsBoC,GAAc,IACtCxB,GAAKwB,EAAauH,WAC1BrE,EAAQxE,GAAKsB,EAAasH,WACjB1H,IACTsD,EAAQ1E,EAAIyH,GAAoBrG,KAI7B,CACLpB,EAAGwI,EAAK5O,KAAO2M,EAAOc,WAAa3C,EAAQ1E,EAC3CE,EAAGsI,EAAK/K,IAAM8I,EAAOgB,UAAY7C,EAAQxE,EACzCP,MAAO6I,EAAK7I,MACZE,OAAQ2I,EAAK3I,OAEjB,CGvDA,SAASoS,GAAMC,GACb,IAAItT,EAAM,IAAIoO,IACVmF,EAAU,IAAIC,IACdC,EAAS,GAKb,SAAS3F,EAAK4F,GACZH,EAAQI,IAAID,EAASlW,MACN,GAAG3B,OAAO6X,EAASxU,UAAY,GAAIwU,EAASnO,kBAAoB,IACtEvH,SAAQ,SAAU4V,GACzB,IAAKL,EAAQM,IAAID,GAAM,CACrB,IAAIE,EAAc9T,EAAI3F,IAAIuZ,GAEtBE,GACFhG,EAAKgG,EAET,CACF,IACAL,EAAO3E,KAAK4E,EACd,CAQA,OAzBAJ,EAAUtV,SAAQ,SAAU0V,GAC1B1T,EAAIiP,IAAIyE,EAASlW,KAAMkW,EACzB,IAiBAJ,EAAUtV,SAAQ,SAAU0V,GACrBH,EAAQM,IAAIH,EAASlW,OAExBsQ,EAAK4F,EAET,IACOD,CACT,CCvBA,IAAIM,GAAkB,CACpBnY,UAAW,SACX0X,UAAW,GACX1U,SAAU,YAGZ,SAASoV,KACP,IAAK,IAAI1B,EAAO2B,UAAUrG,OAAQsG,EAAO,IAAIpU,MAAMwS,GAAO6B,EAAO,EAAGA,EAAO7B,EAAM6B,IAC/ED,EAAKC,GAAQF,UAAUE,GAGzB,OAAQD,EAAKvE,MAAK,SAAUlT,GAC1B,QAASA,GAAoD,mBAAlCA,EAAQ+D,sBACrC,GACF,CAEO,SAAS4T,GAAgBC,QACL,IAArBA,IACFA,EAAmB,CAAC,GAGtB,IAAIC,EAAoBD,EACpBE,EAAwBD,EAAkBE,iBAC1CA,OAA6C,IAA1BD,EAAmC,GAAKA,EAC3DE,EAAyBH,EAAkBI,eAC3CA,OAA4C,IAA3BD,EAAoCV,GAAkBU,EAC3E,OAAO,SAAsBjZ,EAAWD,EAAQoD,QAC9B,IAAZA,IACFA,EAAU+V,GAGZ,ICxC6B/W,EAC3BgX,EDuCE9W,EAAQ,CACVjC,UAAW,SACXgZ,iBAAkB,GAClBjW,QAASzE,OAAOkE,OAAO,CAAC,EAAG2V,GAAiBW,GAC5C1Q,cAAe,CAAC,EAChBjG,SAAU,CACRvC,UAAWA,EACXD,OAAQA,GAEV4C,WAAY,CAAC,EACbD,OAAQ,CAAC,GAEP2W,EAAmB,GACnBC,GAAc,EACdrN,EAAW,CACb5J,MAAOA,EACPkX,WAAY,SAAoBC,GAC9B,IAAIrW,EAAsC,mBAArBqW,EAAkCA,EAAiBnX,EAAMc,SAAWqW,EACzFC,IACApX,EAAMc,QAAUzE,OAAOkE,OAAO,CAAC,EAAGsW,EAAgB7W,EAAMc,QAASA,GACjEd,EAAMiK,cAAgB,CACpBtM,UAAW0B,EAAU1B,GAAa6N,GAAkB7N,GAAaA,EAAU4Q,eAAiB/C,GAAkB7N,EAAU4Q,gBAAkB,GAC1I7Q,OAAQ8N,GAAkB9N,IAI5B,IElE4B+X,EAC9B4B,EFiEMN,EDhCG,SAAwBtB,GAErC,IAAIsB,EAAmBvB,GAAMC,GAE7B,OAAO/W,EAAeb,QAAO,SAAUC,EAAK+B,GAC1C,OAAO/B,EAAIE,OAAO+Y,EAAiBvR,QAAO,SAAUqQ,GAClD,OAAOA,EAAShW,QAAUA,CAC5B,IACF,GAAG,GACL,CCuB+ByX,EElEK7B,EFkEsB,GAAGzX,OAAO2Y,EAAkB3W,EAAMc,QAAQ2U,WEjE9F4B,EAAS5B,EAAU5X,QAAO,SAAUwZ,EAAQE,GAC9C,IAAIC,EAAWH,EAAOE,EAAQ5X,MAK9B,OAJA0X,EAAOE,EAAQ5X,MAAQ6X,EAAWnb,OAAOkE,OAAO,CAAC,EAAGiX,EAAUD,EAAS,CACrEzW,QAASzE,OAAOkE,OAAO,CAAC,EAAGiX,EAAS1W,QAASyW,EAAQzW,SACrD4I,KAAMrN,OAAOkE,OAAO,CAAC,EAAGiX,EAAS9N,KAAM6N,EAAQ7N,QAC5C6N,EACEF,CACT,GAAG,CAAC,GAEGhb,OAAO4D,KAAKoX,GAAQlV,KAAI,SAAUhG,GACvC,OAAOkb,EAAOlb,EAChB,MF4DM,OAJA6D,EAAM+W,iBAAmBA,EAAiBvR,QAAO,SAAUiS,GACzD,OAAOA,EAAE7X,OACX,IA+FFI,EAAM+W,iBAAiB5W,SAAQ,SAAUJ,GACvC,IAAIJ,EAAOI,EAAKJ,KACZ+X,EAAe3X,EAAKe,QACpBA,OAA2B,IAAjB4W,EAA0B,CAAC,EAAIA,EACzChX,EAASX,EAAKW,OAElB,GAAsB,mBAAXA,EAAuB,CAChC,IAAIiX,EAAYjX,EAAO,CACrBV,MAAOA,EACPL,KAAMA,EACNiK,SAAUA,EACV9I,QAASA,IAKXkW,EAAiB/F,KAAK0G,GAFT,WAAmB,EAGlC,CACF,IA/GS/N,EAASQ,QAClB,EAMAwN,YAAa,WACX,IAAIX,EAAJ,CAIA,IAAIY,EAAkB7X,EAAME,SACxBvC,EAAYka,EAAgBla,UAC5BD,EAASma,EAAgBna,OAG7B,GAAKyY,GAAiBxY,EAAWD,GAAjC,CAKAsC,EAAMwG,MAAQ,CACZ7I,UAAWwX,GAAiBxX,EAAWqH,EAAgBtH,GAAoC,UAA3BsC,EAAMc,QAAQC,UAC9ErD,OAAQiG,EAAcjG,IAOxBsC,EAAM0R,OAAQ,EACd1R,EAAMjC,UAAYiC,EAAMc,QAAQ/C,UAKhCiC,EAAM+W,iBAAiB5W,SAAQ,SAAU0V,GACvC,OAAO7V,EAAMmG,cAAc0P,EAASlW,MAAQtD,OAAOkE,OAAO,CAAC,EAAGsV,EAASnM,KACzE,IAEA,IAAK,IAAIoO,EAAQ,EAAGA,EAAQ9X,EAAM+W,iBAAiBhH,OAAQ+H,IACzD,IAAoB,IAAhB9X,EAAM0R,MAAV,CAMA,IAAIqG,EAAwB/X,EAAM+W,iBAAiBe,GAC/ChY,EAAKiY,EAAsBjY,GAC3BkY,EAAyBD,EAAsBjX,QAC/CoM,OAAsC,IAA3B8K,EAAoC,CAAC,EAAIA,EACpDrY,EAAOoY,EAAsBpY,KAEf,mBAAPG,IACTE,EAAQF,EAAG,CACTE,MAAOA,EACPc,QAASoM,EACTvN,KAAMA,EACNiK,SAAUA,KACN5J,EAdR,MAHEA,EAAM0R,OAAQ,EACdoG,GAAS,CAzBb,CATA,CAqDF,EAGA1N,QC1I2BtK,ED0IV,WACf,OAAO,IAAImY,SAAQ,SAAUC,GAC3BtO,EAASgO,cACTM,EAAQlY,EACV,GACF,EC7IG,WAUL,OATK8W,IACHA,EAAU,IAAImB,SAAQ,SAAUC,GAC9BD,QAAQC,UAAUC,MAAK,WACrBrB,OAAUsB,EACVF,EAAQpY,IACV,GACF,KAGKgX,CACT,GDmIIuB,QAAS,WACPjB,IACAH,GAAc,CAChB,GAGF,IAAKd,GAAiBxY,EAAWD,GAC/B,OAAOkM,EAmCT,SAASwN,IACPJ,EAAiB7W,SAAQ,SAAUL,GACjC,OAAOA,GACT,IACAkX,EAAmB,EACrB,CAEA,OAvCApN,EAASsN,WAAWpW,GAASqX,MAAK,SAAUnY,IACrCiX,GAAenW,EAAQwX,eAC1BxX,EAAQwX,cAActY,EAE1B,IAmCO4J,CACT,CACF,CACO,IAAI2O,GAA4BhC,KGzLnC,GAA4BA,GAAgB,CAC9CI,iBAFqB,CAAC6B,GAAgB,GAAe,GAAe,EAAa,GAAQ,GAAM,GAAiB,EAAO,MCJrH,GAA4BjC,GAAgB,CAC9CI,iBAFqB,CAAC6B,GAAgB,GAAe,GAAe,KCatE,MAAMC,GAAa,IAAIlI,IACjBmI,GAAO,CACX,GAAAtH,CAAIxS,EAASzC,EAAKyN,GACX6O,GAAWzC,IAAIpX,IAClB6Z,GAAWrH,IAAIxS,EAAS,IAAI2R,KAE9B,MAAMoI,EAAcF,GAAWjc,IAAIoC,GAI9B+Z,EAAY3C,IAAI7Z,IAA6B,IAArBwc,EAAYC,KAKzCD,EAAYvH,IAAIjV,EAAKyN,GAHnBiP,QAAQC,MAAM,+EAA+E7W,MAAM8W,KAAKJ,EAAY1Y,QAAQ,MAIhI,EACAzD,IAAG,CAACoC,EAASzC,IACPsc,GAAWzC,IAAIpX,IACV6Z,GAAWjc,IAAIoC,GAASpC,IAAIL,IAE9B,KAET,MAAA6c,CAAOpa,EAASzC,GACd,IAAKsc,GAAWzC,IAAIpX,GAClB,OAEF,MAAM+Z,EAAcF,GAAWjc,IAAIoC,GACnC+Z,EAAYM,OAAO9c,GAGM,IAArBwc,EAAYC,MACdH,GAAWQ,OAAOra,EAEtB,GAYIsa,GAAiB,gBAOjBC,GAAgBC,IAChBA,GAAYna,OAAOoa,KAAOpa,OAAOoa,IAAIC,SAEvCF,EAAWA,EAAS5O,QAAQ,iBAAiB,CAAC+O,EAAOC,IAAO,IAAIH,IAAIC,OAAOE,QAEtEJ,GA4CHK,GAAuB7a,IAC3BA,EAAQ8a,cAAc,IAAIC,MAAMT,IAAgB,EAE5C,GAAYU,MACXA,GAA4B,iBAAXA,UAGO,IAAlBA,EAAOC,SAChBD,EAASA,EAAO,SAEgB,IAApBA,EAAOE,UAEjBC,GAAaH,GAEb,GAAUA,GACLA,EAAOC,OAASD,EAAO,GAAKA,EAEf,iBAAXA,GAAuBA,EAAO7J,OAAS,EACzCrL,SAAS+C,cAAc0R,GAAcS,IAEvC,KAEHI,GAAYpb,IAChB,IAAK,GAAUA,IAAgD,IAApCA,EAAQqb,iBAAiBlK,OAClD,OAAO,EAET,MAAMmK,EAAgF,YAA7D5V,iBAAiB1F,GAASub,iBAAiB,cAE9DC,EAAgBxb,EAAQyb,QAAQ,uBACtC,IAAKD,EACH,OAAOF,EAET,GAAIE,IAAkBxb,EAAS,CAC7B,MAAM0b,EAAU1b,EAAQyb,QAAQ,WAChC,GAAIC,GAAWA,EAAQlW,aAAegW,EACpC,OAAO,EAET,GAAgB,OAAZE,EACF,OAAO,CAEX,CACA,OAAOJ,CAAgB,EAEnBK,GAAa3b,IACZA,GAAWA,EAAQkb,WAAaU,KAAKC,gBAGtC7b,EAAQ8b,UAAU7W,SAAS,mBAGC,IAArBjF,EAAQ+b,SACV/b,EAAQ+b,SAEV/b,EAAQgc,aAAa,aAAoD,UAArChc,EAAQic,aAAa,aAE5DC,GAAiBlc,IACrB,IAAK8F,SAASC,gBAAgBoW,aAC5B,OAAO,KAIT,GAAmC,mBAAxBnc,EAAQqF,YAA4B,CAC7C,MAAM+W,EAAOpc,EAAQqF,cACrB,OAAO+W,aAAgBtb,WAAasb,EAAO,IAC7C,CACA,OAAIpc,aAAmBc,WACdd,EAIJA,EAAQwF,WAGN0W,GAAelc,EAAQwF,YAFrB,IAEgC,EAErC6W,GAAO,OAUPC,GAAStc,IACbA,EAAQuE,YAAY,EAGhBgY,GAAY,IACZlc,OAAOmc,SAAW1W,SAAS6G,KAAKqP,aAAa,qBACxC3b,OAAOmc,OAET,KAEHC,GAA4B,GAgB5BC,GAAQ,IAAuC,QAAjC5W,SAASC,gBAAgB4W,IACvCC,GAAqBC,IAhBAC,QAiBN,KACjB,MAAMC,EAAIR,KAEV,GAAIQ,EAAG,CACL,MAAMhc,EAAO8b,EAAOG,KACdC,EAAqBF,EAAE7b,GAAGH,GAChCgc,EAAE7b,GAAGH,GAAQ8b,EAAOK,gBACpBH,EAAE7b,GAAGH,GAAMoc,YAAcN,EACzBE,EAAE7b,GAAGH,GAAMqc,WAAa,KACtBL,EAAE7b,GAAGH,GAAQkc,EACNJ,EAAOK,gBAElB,GA5B0B,YAAxBpX,SAASuX,YAENZ,GAA0BtL,QAC7BrL,SAASyF,iBAAiB,oBAAoB,KAC5C,IAAK,MAAMuR,KAAYL,GACrBK,GACF,IAGJL,GAA0BpK,KAAKyK,IAE/BA,GAkBA,EAEEQ,GAAU,CAACC,EAAkB9F,EAAO,GAAI+F,EAAeD,IACxB,mBAArBA,EAAkCA,KAAoB9F,GAAQ+F,EAExEC,GAAyB,CAACX,EAAUY,EAAmBC,GAAoB,KAC/E,IAAKA,EAEH,YADAL,GAAQR,GAGV,MACMc,EAhKiC5d,KACvC,IAAKA,EACH,OAAO,EAIT,IAAI,mBACF6d,EAAkB,gBAClBC,GACEzd,OAAOqF,iBAAiB1F,GAC5B,MAAM+d,EAA0BC,OAAOC,WAAWJ,GAC5CK,EAAuBF,OAAOC,WAAWH,GAG/C,OAAKC,GAA4BG,GAKjCL,EAAqBA,EAAmBlb,MAAM,KAAK,GACnDmb,EAAkBA,EAAgBnb,MAAM,KAAK,GAtDf,KAuDtBqb,OAAOC,WAAWJ,GAAsBG,OAAOC,WAAWH,KANzD,CAMoG,EA2IpFK,CAAiCT,GADlC,EAExB,IAAIU,GAAS,EACb,MAAMC,EAAU,EACdrR,aAEIA,IAAW0Q,IAGfU,GAAS,EACTV,EAAkBjS,oBAAoB6O,GAAgB+D,GACtDf,GAAQR,GAAS,EAEnBY,EAAkBnS,iBAAiB+O,GAAgB+D,GACnDC,YAAW,KACJF,GACHvD,GAAqB6C,EACvB,GACCE,EAAiB,EAYhBW,GAAuB,CAAC1R,EAAM2R,EAAeC,EAAeC,KAChE,MAAMC,EAAa9R,EAAKsE,OACxB,IAAI+H,EAAQrM,EAAKjH,QAAQ4Y,GAIzB,OAAe,IAAXtF,GACMuF,GAAiBC,EAAiB7R,EAAK8R,EAAa,GAAK9R,EAAK,IAExEqM,GAASuF,EAAgB,GAAK,EAC1BC,IACFxF,GAASA,EAAQyF,GAAcA,GAE1B9R,EAAKjK,KAAKC,IAAI,EAAGD,KAAKE,IAAIoW,EAAOyF,EAAa,KAAI,EAerDC,GAAiB,qBACjBC,GAAiB,OACjBC,GAAgB,SAChBC,GAAgB,CAAC,EACvB,IAAIC,GAAW,EACf,MAAMC,GAAe,CACnBC,WAAY,YACZC,WAAY,YAERC,GAAe,IAAIrI,IAAI,CAAC,QAAS,WAAY,UAAW,YAAa,cAAe,aAAc,iBAAkB,YAAa,WAAY,YAAa,cAAe,YAAa,UAAW,WAAY,QAAS,oBAAqB,aAAc,YAAa,WAAY,cAAe,cAAe,cAAe,YAAa,eAAgB,gBAAiB,eAAgB,gBAAiB,aAAc,QAAS,OAAQ,SAAU,QAAS,SAAU,SAAU,UAAW,WAAY,OAAQ,SAAU,eAAgB,SAAU,OAAQ,mBAAoB,mBAAoB,QAAS,QAAS,WAM/lB,SAASsI,GAAarf,EAASsf,GAC7B,OAAOA,GAAO,GAAGA,MAAQN,QAAgBhf,EAAQgf,UAAYA,IAC/D,CACA,SAASO,GAAiBvf,GACxB,MAAMsf,EAAMD,GAAarf,GAGzB,OAFAA,EAAQgf,SAAWM,EACnBP,GAAcO,GAAOP,GAAcO,IAAQ,CAAC,EACrCP,GAAcO,EACvB,CAiCA,SAASE,GAAYC,EAAQC,EAAUC,EAAqB,MAC1D,OAAOliB,OAAOmiB,OAAOH,GAAQ7M,MAAKiN,GAASA,EAAMH,WAAaA,GAAYG,EAAMF,qBAAuBA,GACzG,CACA,SAASG,GAAoBC,EAAmB1B,EAAS2B,GACvD,MAAMC,EAAiC,iBAAZ5B,EAErBqB,EAAWO,EAAcD,EAAqB3B,GAAW2B,EAC/D,IAAIE,EAAYC,GAAaJ,GAI7B,OAHKX,GAAahI,IAAI8I,KACpBA,EAAYH,GAEP,CAACE,EAAaP,EAAUQ,EACjC,CACA,SAASE,GAAWpgB,EAAS+f,EAAmB1B,EAAS2B,EAAoBK,GAC3E,GAAiC,iBAAtBN,IAAmC/f,EAC5C,OAEF,IAAKigB,EAAaP,EAAUQ,GAAaJ,GAAoBC,EAAmB1B,EAAS2B,GAIzF,GAAID,KAAqBd,GAAc,CACrC,MAAMqB,EAAepf,GACZ,SAAU2e,GACf,IAAKA,EAAMU,eAAiBV,EAAMU,gBAAkBV,EAAMW,iBAAmBX,EAAMW,eAAevb,SAAS4a,EAAMU,eAC/G,OAAOrf,EAAGjD,KAAKwiB,KAAMZ,EAEzB,EAEFH,EAAWY,EAAaZ,EAC1B,CACA,MAAMD,EAASF,GAAiBvf,GAC1B0gB,EAAWjB,EAAOS,KAAeT,EAAOS,GAAa,CAAC,GACtDS,EAAmBnB,GAAYkB,EAAUhB,EAAUO,EAAc5B,EAAU,MACjF,GAAIsC,EAEF,YADAA,EAAiBN,OAASM,EAAiBN,QAAUA,GAGvD,MAAMf,EAAMD,GAAaK,EAAUK,EAAkBnU,QAAQgT,GAAgB,KACvE1d,EAAK+e,EA5Db,SAAoCjgB,EAASwa,EAAUtZ,GACrD,OAAO,SAASmd,EAAQwB,GACtB,MAAMe,EAAc5gB,EAAQ6gB,iBAAiBrG,GAC7C,IAAK,IAAI,OACPxN,GACE6S,EAAO7S,GAAUA,IAAWyT,KAAMzT,EAASA,EAAOxH,WACpD,IAAK,MAAMsb,KAAcF,EACvB,GAAIE,IAAe9T,EASnB,OANA+T,GAAWlB,EAAO,CAChBW,eAAgBxT,IAEdqR,EAAQgC,QACVW,GAAaC,IAAIjhB,EAAS6f,EAAMqB,KAAM1G,EAAUtZ,GAE3CA,EAAGigB,MAAMnU,EAAQ,CAAC6S,GAG/B,CACF,CAwC2BuB,CAA2BphB,EAASqe,EAASqB,GAvExE,SAA0B1f,EAASkB,GACjC,OAAO,SAASmd,EAAQwB,GAOtB,OANAkB,GAAWlB,EAAO,CAChBW,eAAgBxgB,IAEdqe,EAAQgC,QACVW,GAAaC,IAAIjhB,EAAS6f,EAAMqB,KAAMhgB,GAEjCA,EAAGigB,MAAMnhB,EAAS,CAAC6f,GAC5B,CACF,CA6DoFwB,CAAiBrhB,EAAS0f,GAC5Gxe,EAAGye,mBAAqBM,EAAc5B,EAAU,KAChDnd,EAAGwe,SAAWA,EACdxe,EAAGmf,OAASA,EACZnf,EAAG8d,SAAWM,EACdoB,EAASpB,GAAOpe,EAChBlB,EAAQuL,iBAAiB2U,EAAWhf,EAAI+e,EAC1C,CACA,SAASqB,GAActhB,EAASyf,EAAQS,EAAW7B,EAASsB,GAC1D,MAAMze,EAAKse,GAAYC,EAAOS,GAAY7B,EAASsB,GAC9Cze,IAGLlB,EAAQyL,oBAAoByU,EAAWhf,EAAIqgB,QAAQ5B,WAC5CF,EAAOS,GAAWhf,EAAG8d,UAC9B,CACA,SAASwC,GAAyBxhB,EAASyf,EAAQS,EAAWuB,GAC5D,MAAMC,EAAoBjC,EAAOS,IAAc,CAAC,EAChD,IAAK,MAAOyB,EAAY9B,KAAUpiB,OAAOmkB,QAAQF,GAC3CC,EAAWE,SAASJ,IACtBH,GAActhB,EAASyf,EAAQS,EAAWL,EAAMH,SAAUG,EAAMF,mBAGtE,CACA,SAASQ,GAAaN,GAGpB,OADAA,EAAQA,EAAMjU,QAAQiT,GAAgB,IAC/BI,GAAaY,IAAUA,CAChC,CACA,MAAMmB,GAAe,CACnB,EAAAc,CAAG9hB,EAAS6f,EAAOxB,EAAS2B,GAC1BI,GAAWpgB,EAAS6f,EAAOxB,EAAS2B,GAAoB,EAC1D,EACA,GAAA+B,CAAI/hB,EAAS6f,EAAOxB,EAAS2B,GAC3BI,GAAWpgB,EAAS6f,EAAOxB,EAAS2B,GAAoB,EAC1D,EACA,GAAAiB,CAAIjhB,EAAS+f,EAAmB1B,EAAS2B,GACvC,GAAiC,iBAAtBD,IAAmC/f,EAC5C,OAEF,MAAOigB,EAAaP,EAAUQ,GAAaJ,GAAoBC,EAAmB1B,EAAS2B,GACrFgC,EAAc9B,IAAcH,EAC5BN,EAASF,GAAiBvf,GAC1B0hB,EAAoBjC,EAAOS,IAAc,CAAC,EAC1C+B,EAAclC,EAAkBmC,WAAW,KACjD,QAAwB,IAAbxC,EAAX,CAQA,GAAIuC,EACF,IAAK,MAAME,KAAgB1kB,OAAO4D,KAAKoe,GACrC+B,GAAyBxhB,EAASyf,EAAQ0C,EAAcpC,EAAkBlN,MAAM,IAGpF,IAAK,MAAOuP,EAAavC,KAAUpiB,OAAOmkB,QAAQF,GAAoB,CACpE,MAAMC,EAAaS,EAAYxW,QAAQkT,GAAe,IACjDkD,IAAejC,EAAkB8B,SAASF,IAC7CL,GAActhB,EAASyf,EAAQS,EAAWL,EAAMH,SAAUG,EAAMF,mBAEpE,CAXA,KAPA,CAEE,IAAKliB,OAAO4D,KAAKqgB,GAAmBvQ,OAClC,OAEFmQ,GAActhB,EAASyf,EAAQS,EAAWR,EAAUO,EAAc5B,EAAU,KAE9E,CAYF,EACA,OAAAgE,CAAQriB,EAAS6f,EAAOpI,GACtB,GAAqB,iBAAVoI,IAAuB7f,EAChC,OAAO,KAET,MAAM+c,EAAIR,KAGV,IAAI+F,EAAc,KACdC,GAAU,EACVC,GAAiB,EACjBC,GAAmB,EAJH5C,IADFM,GAAaN,IAMZ9C,IACjBuF,EAAcvF,EAAEhC,MAAM8E,EAAOpI,GAC7BsF,EAAE/c,GAASqiB,QAAQC,GACnBC,GAAWD,EAAYI,uBACvBF,GAAkBF,EAAYK,gCAC9BF,EAAmBH,EAAYM,sBAEjC,MAAMC,EAAM9B,GAAW,IAAIhG,MAAM8E,EAAO,CACtC0C,UACAO,YAAY,IACVrL,GAUJ,OATIgL,GACFI,EAAIE,iBAEFP,GACFxiB,EAAQ8a,cAAc+H,GAEpBA,EAAIJ,kBAAoBH,GAC1BA,EAAYS,iBAEPF,CACT,GAEF,SAAS9B,GAAWljB,EAAKmlB,EAAO,CAAC,GAC/B,IAAK,MAAOzlB,EAAKa,KAAUX,OAAOmkB,QAAQoB,GACxC,IACEnlB,EAAIN,GAAOa,CACb,CAAE,MAAO6kB,GACPxlB,OAAOC,eAAeG,EAAKN,EAAK,CAC9B2lB,cAAc,EACdtlB,IAAG,IACMQ,GAGb,CAEF,OAAOP,CACT,CASA,SAASslB,GAAc/kB,GACrB,GAAc,SAAVA,EACF,OAAO,EAET,GAAc,UAAVA,EACF,OAAO,EAET,GAAIA,IAAU4f,OAAO5f,GAAOkC,WAC1B,OAAO0d,OAAO5f,GAEhB,GAAc,KAAVA,GAA0B,SAAVA,EAClB,OAAO,KAET,GAAqB,iBAAVA,EACT,OAAOA,EAET,IACE,OAAOglB,KAAKC,MAAMC,mBAAmBllB,GACvC,CAAE,MAAO6kB,GACP,OAAO7kB,CACT,CACF,CACA,SAASmlB,GAAiBhmB,GACxB,OAAOA,EAAIqO,QAAQ,UAAU4X,GAAO,IAAIA,EAAItjB,iBAC9C,CACA,MAAMujB,GAAc,CAClB,gBAAAC,CAAiB1jB,EAASzC,EAAKa,GAC7B4B,EAAQ6B,aAAa,WAAW0hB,GAAiBhmB,KAAQa,EAC3D,EACA,mBAAAulB,CAAoB3jB,EAASzC,GAC3ByC,EAAQ4B,gBAAgB,WAAW2hB,GAAiBhmB,KACtD,EACA,iBAAAqmB,CAAkB5jB,GAChB,IAAKA,EACH,MAAO,CAAC,EAEV,MAAM0B,EAAa,CAAC,EACdmiB,EAASpmB,OAAO4D,KAAKrB,EAAQ8jB,SAASld,QAAOrJ,GAAOA,EAAI2kB,WAAW,QAAU3kB,EAAI2kB,WAAW,cAClG,IAAK,MAAM3kB,KAAOsmB,EAAQ,CACxB,IAAIE,EAAUxmB,EAAIqO,QAAQ,MAAO,IACjCmY,EAAUA,EAAQC,OAAO,GAAG9jB,cAAgB6jB,EAAQlR,MAAM,EAAGkR,EAAQ5S,QACrEzP,EAAWqiB,GAAWZ,GAAcnjB,EAAQ8jB,QAAQvmB,GACtD,CACA,OAAOmE,CACT,EACAuiB,iBAAgB,CAACjkB,EAASzC,IACjB4lB,GAAcnjB,EAAQic,aAAa,WAAWsH,GAAiBhmB,QAgB1E,MAAM2mB,GAEJ,kBAAWC,GACT,MAAO,CAAC,CACV,CACA,sBAAWC,GACT,MAAO,CAAC,CACV,CACA,eAAWpH,GACT,MAAM,IAAIqH,MAAM,sEAClB,CACA,UAAAC,CAAWC,GAIT,OAHAA,EAAS9D,KAAK+D,gBAAgBD,GAC9BA,EAAS9D,KAAKgE,kBAAkBF,GAChC9D,KAAKiE,iBAAiBH,GACfA,CACT,CACA,iBAAAE,CAAkBF,GAChB,OAAOA,CACT,CACA,eAAAC,CAAgBD,EAAQvkB,GACtB,MAAM2kB,EAAa,GAAU3kB,GAAWyjB,GAAYQ,iBAAiBjkB,EAAS,UAAY,CAAC,EAE3F,MAAO,IACFygB,KAAKmE,YAAYT,WACM,iBAAfQ,EAA0BA,EAAa,CAAC,KAC/C,GAAU3kB,GAAWyjB,GAAYG,kBAAkB5jB,GAAW,CAAC,KAC7C,iBAAXukB,EAAsBA,EAAS,CAAC,EAE/C,CACA,gBAAAG,CAAiBH,EAAQM,EAAcpE,KAAKmE,YAAYR,aACtD,IAAK,MAAO7hB,EAAUuiB,KAAkBrnB,OAAOmkB,QAAQiD,GAAc,CACnE,MAAMzmB,EAAQmmB,EAAOhiB,GACfwiB,EAAY,GAAU3mB,GAAS,UAjiBrC4c,OADSA,EAkiB+C5c,GAhiBnD,GAAG4c,IAELvd,OAAOM,UAAUuC,SAASrC,KAAK+c,GAAQL,MAAM,eAAe,GAAGza,cA+hBlE,IAAK,IAAI8kB,OAAOF,GAAehhB,KAAKihB,GAClC,MAAM,IAAIE,UAAU,GAAGxE,KAAKmE,YAAY5H,KAAKkI,0BAA0B3iB,qBAA4BwiB,yBAAiCD,MAExI,CAtiBW9J,KAuiBb,EAqBF,MAAMmK,WAAsBjB,GAC1B,WAAAU,CAAY5kB,EAASukB,GACnBa,SACAplB,EAAUmb,GAAWnb,MAIrBygB,KAAK4E,SAAWrlB,EAChBygB,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/BzK,GAAKtH,IAAIiO,KAAK4E,SAAU5E,KAAKmE,YAAYW,SAAU9E,MACrD,CAGA,OAAA+E,GACE1L,GAAKM,OAAOqG,KAAK4E,SAAU5E,KAAKmE,YAAYW,UAC5CvE,GAAaC,IAAIR,KAAK4E,SAAU5E,KAAKmE,YAAYa,WACjD,IAAK,MAAMC,KAAgBjoB,OAAOkoB,oBAAoBlF,MACpDA,KAAKiF,GAAgB,IAEzB,CACA,cAAAE,CAAe9I,EAAU9c,EAAS6lB,GAAa,GAC7CpI,GAAuBX,EAAU9c,EAAS6lB,EAC5C,CACA,UAAAvB,CAAWC,GAIT,OAHAA,EAAS9D,KAAK+D,gBAAgBD,EAAQ9D,KAAK4E,UAC3Cd,EAAS9D,KAAKgE,kBAAkBF,GAChC9D,KAAKiE,iBAAiBH,GACfA,CACT,CAGA,kBAAOuB,CAAY9lB,GACjB,OAAO8Z,GAAKlc,IAAIud,GAAWnb,GAAUygB,KAAK8E,SAC5C,CACA,0BAAOQ,CAAoB/lB,EAASukB,EAAS,CAAC,GAC5C,OAAO9D,KAAKqF,YAAY9lB,IAAY,IAAIygB,KAAKzgB,EAA2B,iBAAXukB,EAAsBA,EAAS,KAC9F,CACA,kBAAWyB,GACT,MA5CY,OA6Cd,CACA,mBAAWT,GACT,MAAO,MAAM9E,KAAKzD,MACpB,CACA,oBAAWyI,GACT,MAAO,IAAIhF,KAAK8E,UAClB,CACA,gBAAOU,CAAUllB,GACf,MAAO,GAAGA,IAAO0f,KAAKgF,WACxB,EAUF,MAAMS,GAAclmB,IAClB,IAAIwa,EAAWxa,EAAQic,aAAa,kBACpC,IAAKzB,GAAyB,MAAbA,EAAkB,CACjC,IAAI2L,EAAgBnmB,EAAQic,aAAa,QAMzC,IAAKkK,IAAkBA,EAActE,SAAS,OAASsE,EAAcjE,WAAW,KAC9E,OAAO,KAILiE,EAActE,SAAS,OAASsE,EAAcjE,WAAW,OAC3DiE,EAAgB,IAAIA,EAAcxjB,MAAM,KAAK,MAE/C6X,EAAW2L,GAAmC,MAAlBA,EAAwB5L,GAAc4L,EAAcC,QAAU,IAC5F,CACA,OAAO5L,CAAQ,EAEX6L,GAAiB,CACrBzT,KAAI,CAAC4H,EAAUxa,EAAU8F,SAASC,kBACzB,GAAG3G,UAAUsB,QAAQ3C,UAAU8iB,iBAAiB5iB,KAAK+B,EAASwa,IAEvE8L,QAAO,CAAC9L,EAAUxa,EAAU8F,SAASC,kBAC5BrF,QAAQ3C,UAAU8K,cAAc5K,KAAK+B,EAASwa,GAEvD+L,SAAQ,CAACvmB,EAASwa,IACT,GAAGpb,UAAUY,EAAQumB,UAAU3f,QAAOzB,GAASA,EAAMqhB,QAAQhM,KAEtE,OAAAiM,CAAQzmB,EAASwa,GACf,MAAMiM,EAAU,GAChB,IAAIC,EAAW1mB,EAAQwF,WAAWiW,QAAQjB,GAC1C,KAAOkM,GACLD,EAAQpU,KAAKqU,GACbA,EAAWA,EAASlhB,WAAWiW,QAAQjB,GAEzC,OAAOiM,CACT,EACA,IAAAE,CAAK3mB,EAASwa,GACZ,IAAIoM,EAAW5mB,EAAQ6mB,uBACvB,KAAOD,GAAU,CACf,GAAIA,EAASJ,QAAQhM,GACnB,MAAO,CAACoM,GAEVA,EAAWA,EAASC,sBACtB,CACA,MAAO,EACT,EAEA,IAAAvhB,CAAKtF,EAASwa,GACZ,IAAIlV,EAAOtF,EAAQ8mB,mBACnB,KAAOxhB,GAAM,CACX,GAAIA,EAAKkhB,QAAQhM,GACf,MAAO,CAAClV,GAEVA,EAAOA,EAAKwhB,kBACd,CACA,MAAO,EACT,EACA,iBAAAC,CAAkB/mB,GAChB,MAAMgnB,EAAa,CAAC,IAAK,SAAU,QAAS,WAAY,SAAU,UAAW,aAAc,4BAA4BzjB,KAAIiX,GAAY,GAAGA,2BAAiC7W,KAAK,KAChL,OAAO8c,KAAK7N,KAAKoU,EAAYhnB,GAAS4G,QAAOqgB,IAAOtL,GAAWsL,IAAO7L,GAAU6L,IAClF,EACA,sBAAAC,CAAuBlnB,GACrB,MAAMwa,EAAW0L,GAAYlmB,GAC7B,OAAIwa,GACK6L,GAAeC,QAAQ9L,GAAYA,EAErC,IACT,EACA,sBAAA2M,CAAuBnnB,GACrB,MAAMwa,EAAW0L,GAAYlmB,GAC7B,OAAOwa,EAAW6L,GAAeC,QAAQ9L,GAAY,IACvD,EACA,+BAAA4M,CAAgCpnB,GAC9B,MAAMwa,EAAW0L,GAAYlmB,GAC7B,OAAOwa,EAAW6L,GAAezT,KAAK4H,GAAY,EACpD,GAUI6M,GAAuB,CAACC,EAAWC,EAAS,UAChD,MAAMC,EAAa,gBAAgBF,EAAU7B,YACvC1kB,EAAOumB,EAAUtK,KACvBgE,GAAac,GAAGhc,SAAU0hB,EAAY,qBAAqBzmB,OAAU,SAAU8e,GAI7E,GAHI,CAAC,IAAK,QAAQgC,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAEJpH,GAAW8E,MACb,OAEF,MAAMzT,EAASqZ,GAAec,uBAAuB1G,OAASA,KAAKhF,QAAQ,IAAI1a,KAC9DumB,EAAUvB,oBAAoB/Y,GAGtCua,IACX,GAAE,EAiBEG,GAAc,YACdC,GAAc,QAAQD,KACtBE,GAAe,SAASF,KAQ9B,MAAMG,WAAc1C,GAElB,eAAWnI,GACT,MAfW,OAgBb,CAGA,KAAA8K,GAEE,GADmB9G,GAAaqB,QAAQ5B,KAAK4E,SAAUsC,IACxClF,iBACb,OAEFhC,KAAK4E,SAASvJ,UAAU1B,OAlBF,QAmBtB,MAAMyL,EAAapF,KAAK4E,SAASvJ,UAAU7W,SApBrB,QAqBtBwb,KAAKmF,gBAAe,IAAMnF,KAAKsH,mBAAmBtH,KAAK4E,SAAUQ,EACnE,CAGA,eAAAkC,GACEtH,KAAK4E,SAASjL,SACd4G,GAAaqB,QAAQ5B,KAAK4E,SAAUuC,IACpCnH,KAAK+E,SACP,CAGA,sBAAOtI,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO+c,GAAM9B,oBAAoBtF,MACvC,GAAsB,iBAAX8D,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQ9D,KAJb,CAKF,GACF,EAOF4G,GAAqBQ,GAAO,SAM5BjL,GAAmBiL,IAcnB,MAKMI,GAAyB,4BAO/B,MAAMC,WAAe/C,GAEnB,eAAWnI,GACT,MAfW,QAgBb,CAGA,MAAAmL,GAEE1H,KAAK4E,SAASxjB,aAAa,eAAgB4e,KAAK4E,SAASvJ,UAAUqM,OAjB3C,UAkB1B,CAGA,sBAAOjL,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOod,GAAOnC,oBAAoBtF,MACzB,WAAX8D,GACFzZ,EAAKyZ,IAET,GACF,EAOFvD,GAAac,GAAGhc,SAjCe,2BAiCmBmiB,IAAwBpI,IACxEA,EAAMkD,iBACN,MAAMqF,EAASvI,EAAM7S,OAAOyO,QAAQwM,IACvBC,GAAOnC,oBAAoBqC,GACnCD,QAAQ,IAOfvL,GAAmBsL,IAcnB,MACMG,GAAc,YACdC,GAAmB,aAAaD,KAChCE,GAAkB,YAAYF,KAC9BG,GAAiB,WAAWH,KAC5BI,GAAoB,cAAcJ,KAClCK,GAAkB,YAAYL,KAK9BM,GAAY,CAChBC,YAAa,KACbC,aAAc,KACdC,cAAe,MAEXC,GAAgB,CACpBH,YAAa,kBACbC,aAAc,kBACdC,cAAe,mBAOjB,MAAME,WAAc9E,GAClB,WAAAU,CAAY5kB,EAASukB,GACnBa,QACA3E,KAAK4E,SAAWrlB,EACXA,GAAYgpB,GAAMC,gBAGvBxI,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/B9D,KAAKyI,QAAU,EACfzI,KAAK0I,sBAAwB5H,QAAQlhB,OAAO+oB,cAC5C3I,KAAK4I,cACP,CAGA,kBAAWlF,GACT,OAAOwE,EACT,CACA,sBAAWvE,GACT,OAAO2E,EACT,CACA,eAAW/L,GACT,MA/CW,OAgDb,CAGA,OAAAwI,GACExE,GAAaC,IAAIR,KAAK4E,SAAUgD,GAClC,CAGA,MAAAiB,CAAOzJ,GACAY,KAAK0I,sBAIN1I,KAAK8I,wBAAwB1J,KAC/BY,KAAKyI,QAAUrJ,EAAM2J,SAJrB/I,KAAKyI,QAAUrJ,EAAM4J,QAAQ,GAAGD,OAMpC,CACA,IAAAE,CAAK7J,GACCY,KAAK8I,wBAAwB1J,KAC/BY,KAAKyI,QAAUrJ,EAAM2J,QAAU/I,KAAKyI,SAEtCzI,KAAKkJ,eACLrM,GAAQmD,KAAK6E,QAAQsD,YACvB,CACA,KAAAgB,CAAM/J,GACJY,KAAKyI,QAAUrJ,EAAM4J,SAAW5J,EAAM4J,QAAQtY,OAAS,EAAI,EAAI0O,EAAM4J,QAAQ,GAAGD,QAAU/I,KAAKyI,OACjG,CACA,YAAAS,GACE,MAAME,EAAYjnB,KAAKoC,IAAIyb,KAAKyI,SAChC,GAAIW,GAnEgB,GAoElB,OAEF,MAAM9b,EAAY8b,EAAYpJ,KAAKyI,QACnCzI,KAAKyI,QAAU,EACVnb,GAGLuP,GAAQvP,EAAY,EAAI0S,KAAK6E,QAAQwD,cAAgBrI,KAAK6E,QAAQuD,aACpE,CACA,WAAAQ,GACM5I,KAAK0I,uBACPnI,GAAac,GAAGrB,KAAK4E,SAAUoD,IAAmB5I,GAASY,KAAK6I,OAAOzJ,KACvEmB,GAAac,GAAGrB,KAAK4E,SAAUqD,IAAiB7I,GAASY,KAAKiJ,KAAK7J,KACnEY,KAAK4E,SAASvJ,UAAU5E,IAlFG,mBAoF3B8J,GAAac,GAAGrB,KAAK4E,SAAUiD,IAAkBzI,GAASY,KAAK6I,OAAOzJ,KACtEmB,GAAac,GAAGrB,KAAK4E,SAAUkD,IAAiB1I,GAASY,KAAKmJ,MAAM/J,KACpEmB,GAAac,GAAGrB,KAAK4E,SAAUmD,IAAgB3I,GAASY,KAAKiJ,KAAK7J,KAEtE,CACA,uBAAA0J,CAAwB1J,GACtB,OAAOY,KAAK0I,wBA3FS,QA2FiBtJ,EAAMiK,aA5FrB,UA4FyDjK,EAAMiK,YACxF,CAGA,kBAAOb,GACL,MAAO,iBAAkBnjB,SAASC,iBAAmB7C,UAAU6mB,eAAiB,CAClF,EAeF,MAEMC,GAAc,eACdC,GAAiB,YAKjBC,GAAa,OACbC,GAAa,OACbC,GAAiB,OACjBC,GAAkB,QAClBC,GAAc,QAAQN,KACtBO,GAAa,OAAOP,KACpBQ,GAAkB,UAAUR,KAC5BS,GAAqB,aAAaT,KAClCU,GAAqB,aAAaV,KAClCW,GAAmB,YAAYX,KAC/BY,GAAwB,OAAOZ,KAAcC,KAC7CY,GAAyB,QAAQb,KAAcC,KAC/Ca,GAAsB,WACtBC,GAAsB,SAMtBC,GAAkB,UAClBC,GAAgB,iBAChBC,GAAuBF,GAAkBC,GAKzCE,GAAmB,CACvB,UAAoBd,GACpB,WAAqBD,IAEjBgB,GAAY,CAChBC,SAAU,IACVC,UAAU,EACVC,MAAO,QACPC,MAAM,EACNC,OAAO,EACPC,MAAM,GAEFC,GAAgB,CACpBN,SAAU,mBAEVC,SAAU,UACVC,MAAO,mBACPC,KAAM,mBACNC,MAAO,UACPC,KAAM,WAOR,MAAME,WAAiBzG,GACrB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKoL,UAAY,KACjBpL,KAAKqL,eAAiB,KACtBrL,KAAKsL,YAAa,EAClBtL,KAAKuL,aAAe,KACpBvL,KAAKwL,aAAe,KACpBxL,KAAKyL,mBAAqB7F,GAAeC,QArCjB,uBAqC8C7F,KAAK4E,UAC3E5E,KAAK0L,qBACD1L,KAAK6E,QAAQkG,OAASV,IACxBrK,KAAK2L,OAET,CAGA,kBAAWjI,GACT,OAAOiH,EACT,CACA,sBAAWhH,GACT,OAAOuH,EACT,CACA,eAAW3O,GACT,MAnFW,UAoFb,CAGA,IAAA1X,GACEmb,KAAK4L,OAAOnC,GACd,CACA,eAAAoC,IAIOxmB,SAASymB,QAAUnR,GAAUqF,KAAK4E,WACrC5E,KAAKnb,MAET,CACA,IAAAqhB,GACElG,KAAK4L,OAAOlC,GACd,CACA,KAAAoB,GACM9K,KAAKsL,YACPlR,GAAqB4F,KAAK4E,UAE5B5E,KAAK+L,gBACP,CACA,KAAAJ,GACE3L,KAAK+L,iBACL/L,KAAKgM,kBACLhM,KAAKoL,UAAYa,aAAY,IAAMjM,KAAK6L,mBAAmB7L,KAAK6E,QAAQ+F,SAC1E,CACA,iBAAAsB,GACOlM,KAAK6E,QAAQkG,OAGd/K,KAAKsL,WACP/K,GAAae,IAAItB,KAAK4E,SAAUkF,IAAY,IAAM9J,KAAK2L,UAGzD3L,KAAK2L,QACP,CACA,EAAAQ,CAAG1T,GACD,MAAM2T,EAAQpM,KAAKqM,YACnB,GAAI5T,EAAQ2T,EAAM1b,OAAS,GAAK+H,EAAQ,EACtC,OAEF,GAAIuH,KAAKsL,WAEP,YADA/K,GAAae,IAAItB,KAAK4E,SAAUkF,IAAY,IAAM9J,KAAKmM,GAAG1T,KAG5D,MAAM6T,EAActM,KAAKuM,cAAcvM,KAAKwM,cAC5C,GAAIF,IAAgB7T,EAClB,OAEF,MAAMtC,EAAQsC,EAAQ6T,EAAc7C,GAAaC,GACjD1J,KAAK4L,OAAOzV,EAAOiW,EAAM3T,GAC3B,CACA,OAAAsM,GACM/E,KAAKwL,cACPxL,KAAKwL,aAAazG,UAEpBJ,MAAMI,SACR,CAGA,iBAAAf,CAAkBF,GAEhB,OADAA,EAAO2I,gBAAkB3I,EAAO8G,SACzB9G,CACT,CACA,kBAAA4H,GACM1L,KAAK6E,QAAQgG,UACftK,GAAac,GAAGrB,KAAK4E,SAAUmF,IAAiB3K,GAASY,KAAK0M,SAAStN,KAE9C,UAAvBY,KAAK6E,QAAQiG,QACfvK,GAAac,GAAGrB,KAAK4E,SAAUoF,IAAoB,IAAMhK,KAAK8K,UAC9DvK,GAAac,GAAGrB,KAAK4E,SAAUqF,IAAoB,IAAMjK,KAAKkM,uBAE5DlM,KAAK6E,QAAQmG,OAASzC,GAAMC,eAC9BxI,KAAK2M,yBAET,CACA,uBAAAA,GACE,IAAK,MAAMC,KAAOhH,GAAezT,KArIX,qBAqImC6N,KAAK4E,UAC5DrE,GAAac,GAAGuL,EAAK1C,IAAkB9K,GAASA,EAAMkD,mBAExD,MAmBMuK,EAAc,CAClBzE,aAAc,IAAMpI,KAAK4L,OAAO5L,KAAK8M,kBAAkBnD,KACvDtB,cAAe,IAAMrI,KAAK4L,OAAO5L,KAAK8M,kBAAkBlD,KACxDzB,YAtBkB,KACS,UAAvBnI,KAAK6E,QAAQiG,QAYjB9K,KAAK8K,QACD9K,KAAKuL,cACPwB,aAAa/M,KAAKuL,cAEpBvL,KAAKuL,aAAe1N,YAAW,IAAMmC,KAAKkM,qBAjLjB,IAiL+DlM,KAAK6E,QAAQ+F,UAAS,GAOhH5K,KAAKwL,aAAe,IAAIjD,GAAMvI,KAAK4E,SAAUiI,EAC/C,CACA,QAAAH,CAAStN,GACP,GAAI,kBAAkB/b,KAAK+b,EAAM7S,OAAOya,SACtC,OAEF,MAAM1Z,EAAYod,GAAiBtL,EAAMtiB,KACrCwQ,IACF8R,EAAMkD,iBACNtC,KAAK4L,OAAO5L,KAAK8M,kBAAkBxf,IAEvC,CACA,aAAAif,CAAchtB,GACZ,OAAOygB,KAAKqM,YAAYlnB,QAAQ5F,EAClC,CACA,0BAAAytB,CAA2BvU,GACzB,IAAKuH,KAAKyL,mBACR,OAEF,MAAMwB,EAAkBrH,GAAeC,QAAQ0E,GAAiBvK,KAAKyL,oBACrEwB,EAAgB5R,UAAU1B,OAAO2Q,IACjC2C,EAAgB9rB,gBAAgB,gBAChC,MAAM+rB,EAAqBtH,GAAeC,QAAQ,sBAAsBpN,MAAWuH,KAAKyL,oBACpFyB,IACFA,EAAmB7R,UAAU5E,IAAI6T,IACjC4C,EAAmB9rB,aAAa,eAAgB,QAEpD,CACA,eAAA4qB,GACE,MAAMzsB,EAAUygB,KAAKqL,gBAAkBrL,KAAKwM,aAC5C,IAAKjtB,EACH,OAEF,MAAM4tB,EAAkB5P,OAAO6P,SAAS7tB,EAAQic,aAAa,oBAAqB,IAClFwE,KAAK6E,QAAQ+F,SAAWuC,GAAmBnN,KAAK6E,QAAQ4H,eAC1D,CACA,MAAAb,CAAOzV,EAAO5W,EAAU,MACtB,GAAIygB,KAAKsL,WACP,OAEF,MAAMvN,EAAgBiC,KAAKwM,aACrBa,EAASlX,IAAUsT,GACnB6D,EAAc/tB,GAAWue,GAAqBkC,KAAKqM,YAAatO,EAAesP,EAAQrN,KAAK6E,QAAQoG,MAC1G,GAAIqC,IAAgBvP,EAClB,OAEF,MAAMwP,EAAmBvN,KAAKuM,cAAce,GACtCE,EAAehI,GACZjF,GAAaqB,QAAQ5B,KAAK4E,SAAUY,EAAW,CACpD1F,cAAewN,EACfhgB,UAAW0S,KAAKyN,kBAAkBtX,GAClCuD,KAAMsG,KAAKuM,cAAcxO,GACzBoO,GAAIoB,IAIR,GADmBC,EAAa3D,IACjB7H,iBACb,OAEF,IAAKjE,IAAkBuP,EAGrB,OAEF,MAAMI,EAAY5M,QAAQd,KAAKoL,WAC/BpL,KAAK8K,QACL9K,KAAKsL,YAAa,EAClBtL,KAAKgN,2BAA2BO,GAChCvN,KAAKqL,eAAiBiC,EACtB,MAAMK,EAAuBN,EA3OR,sBADF,oBA6ObO,EAAiBP,EA3OH,qBACA,qBA2OpBC,EAAYjS,UAAU5E,IAAImX,GAC1B/R,GAAOyR,GACPvP,EAAc1C,UAAU5E,IAAIkX,GAC5BL,EAAYjS,UAAU5E,IAAIkX,GAQ1B3N,KAAKmF,gBAPoB,KACvBmI,EAAYjS,UAAU1B,OAAOgU,EAAsBC,GACnDN,EAAYjS,UAAU5E,IAAI6T,IAC1BvM,EAAc1C,UAAU1B,OAAO2Q,GAAqBsD,EAAgBD,GACpE3N,KAAKsL,YAAa,EAClBkC,EAAa1D,GAAW,GAEY/L,EAAeiC,KAAK6N,eACtDH,GACF1N,KAAK2L,OAET,CACA,WAAAkC,GACE,OAAO7N,KAAK4E,SAASvJ,UAAU7W,SAhQV,QAiQvB,CACA,UAAAgoB,GACE,OAAO5G,GAAeC,QAAQ4E,GAAsBzK,KAAK4E,SAC3D,CACA,SAAAyH,GACE,OAAOzG,GAAezT,KAAKqY,GAAexK,KAAK4E,SACjD,CACA,cAAAmH,GACM/L,KAAKoL,YACP0C,cAAc9N,KAAKoL,WACnBpL,KAAKoL,UAAY,KAErB,CACA,iBAAA0B,CAAkBxf,GAChB,OAAI2O,KACK3O,IAAcqc,GAAiBD,GAAaD,GAE9Cnc,IAAcqc,GAAiBF,GAAaC,EACrD,CACA,iBAAA+D,CAAkBtX,GAChB,OAAI8F,KACK9F,IAAUuT,GAAaC,GAAiBC,GAE1CzT,IAAUuT,GAAaE,GAAkBD,EAClD,CAGA,sBAAOlN,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO8gB,GAAS7F,oBAAoBtF,KAAM8D,GAChD,GAAsB,iBAAXA,GAIX,GAAsB,iBAAXA,EAAqB,CAC9B,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IACP,OAREzZ,EAAK8hB,GAAGrI,EASZ,GACF,EAOFvD,GAAac,GAAGhc,SAAU+kB,GAvSE,uCAuS2C,SAAUhL,GAC/E,MAAM7S,EAASqZ,GAAec,uBAAuB1G,MACrD,IAAKzT,IAAWA,EAAO8O,UAAU7W,SAAS6lB,IACxC,OAEFjL,EAAMkD,iBACN,MAAMyL,EAAW5C,GAAS7F,oBAAoB/Y,GACxCyhB,EAAahO,KAAKxE,aAAa,oBACrC,OAAIwS,GACFD,EAAS5B,GAAG6B,QACZD,EAAS7B,qBAGyC,SAAhDlJ,GAAYQ,iBAAiBxD,KAAM,UACrC+N,EAASlpB,YACTkpB,EAAS7B,sBAGX6B,EAAS7H,YACT6H,EAAS7B,oBACX,IACA3L,GAAac,GAAGzhB,OAAQuqB,IAAuB,KAC7C,MAAM8D,EAAYrI,GAAezT,KA5TR,6BA6TzB,IAAK,MAAM4b,KAAYE,EACrB9C,GAAS7F,oBAAoByI,EAC/B,IAOF5R,GAAmBgP,IAcnB,MAEM+C,GAAc,eAEdC,GAAe,OAAOD,KACtBE,GAAgB,QAAQF,KACxBG,GAAe,OAAOH,KACtBI,GAAiB,SAASJ,KAC1BK,GAAyB,QAAQL,cACjCM,GAAoB,OACpBC,GAAsB,WACtBC,GAAwB,aAExBC,GAA6B,WAAWF,OAAwBA,KAKhEG,GAAyB,8BACzBC,GAAY,CAChBpqB,OAAQ,KACRijB,QAAQ,GAEJoH,GAAgB,CACpBrqB,OAAQ,iBACRijB,OAAQ,WAOV,MAAMqH,WAAiBrK,GACrB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKgP,kBAAmB,EACxBhP,KAAKiP,cAAgB,GACrB,MAAMC,EAAatJ,GAAezT,KAAKyc,IACvC,IAAK,MAAMO,KAAQD,EAAY,CAC7B,MAAMnV,EAAW6L,GAAea,uBAAuB0I,GACjDC,EAAgBxJ,GAAezT,KAAK4H,GAAU5T,QAAOkpB,GAAgBA,IAAiBrP,KAAK4E,WAChF,OAAb7K,GAAqBqV,EAAc1e,QACrCsP,KAAKiP,cAAcrd,KAAKud,EAE5B,CACAnP,KAAKsP,sBACAtP,KAAK6E,QAAQpgB,QAChBub,KAAKuP,0BAA0BvP,KAAKiP,cAAejP,KAAKwP,YAEtDxP,KAAK6E,QAAQ6C,QACf1H,KAAK0H,QAET,CAGA,kBAAWhE,GACT,OAAOmL,EACT,CACA,sBAAWlL,GACT,OAAOmL,EACT,CACA,eAAWvS,GACT,MA9DW,UA+Db,CAGA,MAAAmL,GACM1H,KAAKwP,WACPxP,KAAKyP,OAELzP,KAAK0P,MAET,CACA,IAAAA,GACE,GAAI1P,KAAKgP,kBAAoBhP,KAAKwP,WAChC,OAEF,IAAIG,EAAiB,GAQrB,GALI3P,KAAK6E,QAAQpgB,SACfkrB,EAAiB3P,KAAK4P,uBAhEH,wCAgE4CzpB,QAAO5G,GAAWA,IAAYygB,KAAK4E,WAAU9hB,KAAIvD,GAAWwvB,GAASzJ,oBAAoB/lB,EAAS,CAC/JmoB,QAAQ,OAGRiI,EAAejf,QAAUif,EAAe,GAAGX,iBAC7C,OAGF,GADmBzO,GAAaqB,QAAQ5B,KAAK4E,SAAUuJ,IACxCnM,iBACb,OAEF,IAAK,MAAM6N,KAAkBF,EAC3BE,EAAeJ,OAEjB,MAAMK,EAAY9P,KAAK+P,gBACvB/P,KAAK4E,SAASvJ,UAAU1B,OAAO8U,IAC/BzO,KAAK4E,SAASvJ,UAAU5E,IAAIiY,IAC5B1O,KAAK4E,SAAS7jB,MAAM+uB,GAAa,EACjC9P,KAAKuP,0BAA0BvP,KAAKiP,eAAe,GACnDjP,KAAKgP,kBAAmB,EACxB,MAQMgB,EAAa,SADUF,EAAU,GAAGrL,cAAgBqL,EAAU1d,MAAM,KAE1E4N,KAAKmF,gBATY,KACfnF,KAAKgP,kBAAmB,EACxBhP,KAAK4E,SAASvJ,UAAU1B,OAAO+U,IAC/B1O,KAAK4E,SAASvJ,UAAU5E,IAAIgY,GAAqBD,IACjDxO,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GACjCvP,GAAaqB,QAAQ5B,KAAK4E,SAAUwJ,GAAc,GAItBpO,KAAK4E,UAAU,GAC7C5E,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GAAG9P,KAAK4E,SAASoL,MACpD,CACA,IAAAP,GACE,GAAIzP,KAAKgP,mBAAqBhP,KAAKwP,WACjC,OAGF,GADmBjP,GAAaqB,QAAQ5B,KAAK4E,SAAUyJ,IACxCrM,iBACb,OAEF,MAAM8N,EAAY9P,KAAK+P,gBACvB/P,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GAAG9P,KAAK4E,SAASthB,wBAAwBwsB,OAC1EjU,GAAOmE,KAAK4E,UACZ5E,KAAK4E,SAASvJ,UAAU5E,IAAIiY,IAC5B1O,KAAK4E,SAASvJ,UAAU1B,OAAO8U,GAAqBD,IACpD,IAAK,MAAM5M,KAAW5B,KAAKiP,cAAe,CACxC,MAAM1vB,EAAUqmB,GAAec,uBAAuB9E,GAClDriB,IAAYygB,KAAKwP,SAASjwB,IAC5BygB,KAAKuP,0BAA0B,CAAC3N,IAAU,EAE9C,CACA5B,KAAKgP,kBAAmB,EAOxBhP,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GACjC9P,KAAKmF,gBAPY,KACfnF,KAAKgP,kBAAmB,EACxBhP,KAAK4E,SAASvJ,UAAU1B,OAAO+U,IAC/B1O,KAAK4E,SAASvJ,UAAU5E,IAAIgY,IAC5BlO,GAAaqB,QAAQ5B,KAAK4E,SAAU0J,GAAe,GAGvBtO,KAAK4E,UAAU,EAC/C,CACA,QAAA4K,CAASjwB,EAAUygB,KAAK4E,UACtB,OAAOrlB,EAAQ8b,UAAU7W,SAASgqB,GACpC,CAGA,iBAAAxK,CAAkBF,GAGhB,OAFAA,EAAO4D,OAAS5G,QAAQgD,EAAO4D,QAC/B5D,EAAOrf,OAASiW,GAAWoJ,EAAOrf,QAC3Bqf,CACT,CACA,aAAAiM,GACE,OAAO/P,KAAK4E,SAASvJ,UAAU7W,SA3IL,uBAChB,QACC,QA0Ib,CACA,mBAAA8qB,GACE,IAAKtP,KAAK6E,QAAQpgB,OAChB,OAEF,MAAMqhB,EAAW9F,KAAK4P,uBAAuBhB,IAC7C,IAAK,MAAMrvB,KAAWumB,EAAU,CAC9B,MAAMmK,EAAWrK,GAAec,uBAAuBnnB,GACnD0wB,GACFjQ,KAAKuP,0BAA0B,CAAChwB,GAAUygB,KAAKwP,SAASS,GAE5D,CACF,CACA,sBAAAL,CAAuB7V,GACrB,MAAM+L,EAAWF,GAAezT,KAAKwc,GAA4B3O,KAAK6E,QAAQpgB,QAE9E,OAAOmhB,GAAezT,KAAK4H,EAAUiG,KAAK6E,QAAQpgB,QAAQ0B,QAAO5G,IAAYumB,EAAS1E,SAAS7hB,IACjG,CACA,yBAAAgwB,CAA0BW,EAAcC,GACtC,GAAKD,EAAaxf,OAGlB,IAAK,MAAMnR,KAAW2wB,EACpB3wB,EAAQ8b,UAAUqM,OArKK,aAqKyByI,GAChD5wB,EAAQ6B,aAAa,gBAAiB+uB,EAE1C,CAGA,sBAAO1T,CAAgBqH,GACrB,MAAMe,EAAU,CAAC,EAIjB,MAHsB,iBAAXf,GAAuB,YAAYzgB,KAAKygB,KACjDe,EAAQ6C,QAAS,GAEZ1H,KAAKuH,MAAK,WACf,MAAMld,EAAO0kB,GAASzJ,oBAAoBtF,KAAM6E,GAChD,GAAsB,iBAAXf,EAAqB,CAC9B,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IACP,CACF,GACF,EAOFvD,GAAac,GAAGhc,SAAUkpB,GAAwBK,IAAwB,SAAUxP,IAErD,MAAzBA,EAAM7S,OAAOya,SAAmB5H,EAAMW,gBAAmD,MAAjCX,EAAMW,eAAeiH,UAC/E5H,EAAMkD,iBAER,IAAK,MAAM/iB,KAAWqmB,GAAee,gCAAgC3G,MACnE+O,GAASzJ,oBAAoB/lB,EAAS,CACpCmoB,QAAQ,IACPA,QAEP,IAMAvL,GAAmB4S,IAcnB,MAAMqB,GAAS,WAETC,GAAc,eACdC,GAAiB,YAGjBC,GAAiB,UACjBC,GAAmB,YAGnBC,GAAe,OAAOJ,KACtBK,GAAiB,SAASL,KAC1BM,GAAe,OAAON,KACtBO,GAAgB,QAAQP,KACxBQ,GAAyB,QAAQR,KAAcC,KAC/CQ,GAAyB,UAAUT,KAAcC,KACjDS,GAAuB,QAAQV,KAAcC,KAC7CU,GAAoB,OAMpBC,GAAyB,4DACzBC,GAA6B,GAAGD,MAA0BD,KAC1DG,GAAgB,iBAIhBC,GAAgBnV,KAAU,UAAY,YACtCoV,GAAmBpV,KAAU,YAAc,UAC3CqV,GAAmBrV,KAAU,aAAe,eAC5CsV,GAAsBtV,KAAU,eAAiB,aACjDuV,GAAkBvV,KAAU,aAAe,cAC3CwV,GAAiBxV,KAAU,cAAgB,aAG3CyV,GAAY,CAChBC,WAAW,EACX1jB,SAAU,kBACV2jB,QAAS,UACT5pB,OAAQ,CAAC,EAAG,GACZ6pB,aAAc,KACdvzB,UAAW,UAEPwzB,GAAgB,CACpBH,UAAW,mBACX1jB,SAAU,mBACV2jB,QAAS,SACT5pB,OAAQ,0BACR6pB,aAAc,yBACdvzB,UAAW,2BAOb,MAAMyzB,WAAiBrN,GACrB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKgS,QAAU,KACfhS,KAAKiS,QAAUjS,KAAK4E,SAAS7f,WAE7Bib,KAAKkS,MAAQtM,GAAe/gB,KAAKmb,KAAK4E,SAAUuM,IAAe,IAAMvL,GAAeM,KAAKlG,KAAK4E,SAAUuM,IAAe,IAAMvL,GAAeC,QAAQsL,GAAenR,KAAKiS,SACxKjS,KAAKmS,UAAYnS,KAAKoS,eACxB,CAGA,kBAAW1O,GACT,OAAOgO,EACT,CACA,sBAAW/N,GACT,OAAOmO,EACT,CACA,eAAWvV,GACT,OAAO6T,EACT,CAGA,MAAA1I,GACE,OAAO1H,KAAKwP,WAAaxP,KAAKyP,OAASzP,KAAK0P,MAC9C,CACA,IAAAA,GACE,GAAIxU,GAAW8E,KAAK4E,WAAa5E,KAAKwP,WACpC,OAEF,MAAM1P,EAAgB,CACpBA,cAAeE,KAAK4E,UAGtB,IADkBrE,GAAaqB,QAAQ5B,KAAK4E,SAAU+L,GAAc7Q,GACtDkC,iBAAd,CASA,GANAhC,KAAKqS,gBAMD,iBAAkBhtB,SAASC,kBAAoB0a,KAAKiS,QAAQjX,QAzExC,eA0EtB,IAAK,MAAMzb,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAac,GAAG9hB,EAAS,YAAaqc,IAG1CoE,KAAK4E,SAAS0N,QACdtS,KAAK4E,SAASxjB,aAAa,iBAAiB,GAC5C4e,KAAKkS,MAAM7W,UAAU5E,IAAIua,IACzBhR,KAAK4E,SAASvJ,UAAU5E,IAAIua,IAC5BzQ,GAAaqB,QAAQ5B,KAAK4E,SAAUgM,GAAe9Q,EAhBnD,CAiBF,CACA,IAAA2P,GACE,GAAIvU,GAAW8E,KAAK4E,YAAc5E,KAAKwP,WACrC,OAEF,MAAM1P,EAAgB,CACpBA,cAAeE,KAAK4E,UAEtB5E,KAAKuS,cAAczS,EACrB,CACA,OAAAiF,GACM/E,KAAKgS,SACPhS,KAAKgS,QAAQhZ,UAEf2L,MAAMI,SACR,CACA,MAAAha,GACEiV,KAAKmS,UAAYnS,KAAKoS,gBAClBpS,KAAKgS,SACPhS,KAAKgS,QAAQjnB,QAEjB,CAGA,aAAAwnB,CAAczS,GAEZ,IADkBS,GAAaqB,QAAQ5B,KAAK4E,SAAU6L,GAAc3Q,GACtDkC,iBAAd,CAMA,GAAI,iBAAkB3c,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAaC,IAAIjhB,EAAS,YAAaqc,IAGvCoE,KAAKgS,SACPhS,KAAKgS,QAAQhZ,UAEfgH,KAAKkS,MAAM7W,UAAU1B,OAAOqX,IAC5BhR,KAAK4E,SAASvJ,UAAU1B,OAAOqX,IAC/BhR,KAAK4E,SAASxjB,aAAa,gBAAiB,SAC5C4hB,GAAYE,oBAAoBlD,KAAKkS,MAAO,UAC5C3R,GAAaqB,QAAQ5B,KAAK4E,SAAU8L,GAAgB5Q,EAhBpD,CAiBF,CACA,UAAA+D,CAAWC,GAET,GAAgC,iBADhCA,EAASa,MAAMd,WAAWC,IACRxlB,YAA2B,GAAUwlB,EAAOxlB,YAAgE,mBAA3CwlB,EAAOxlB,UAAUgF,sBAElG,MAAM,IAAIkhB,UAAU,GAAG4L,GAAO3L,+GAEhC,OAAOX,CACT,CACA,aAAAuO,GACE,QAAsB,IAAX,EACT,MAAM,IAAI7N,UAAU,gEAEtB,IAAIgO,EAAmBxS,KAAK4E,SACG,WAA3B5E,KAAK6E,QAAQvmB,UACfk0B,EAAmBxS,KAAKiS,QACf,GAAUjS,KAAK6E,QAAQvmB,WAChCk0B,EAAmB9X,GAAWsF,KAAK6E,QAAQvmB,WACA,iBAA3B0hB,KAAK6E,QAAQvmB,YAC7Bk0B,EAAmBxS,KAAK6E,QAAQvmB,WAElC,MAAMuzB,EAAe7R,KAAKyS,mBAC1BzS,KAAKgS,QAAU,GAAoBQ,EAAkBxS,KAAKkS,MAAOL,EACnE,CACA,QAAArC,GACE,OAAOxP,KAAKkS,MAAM7W,UAAU7W,SAASwsB,GACvC,CACA,aAAA0B,GACE,MAAMC,EAAiB3S,KAAKiS,QAC5B,GAAIU,EAAetX,UAAU7W,SArKN,WAsKrB,OAAOgtB,GAET,GAAImB,EAAetX,UAAU7W,SAvKJ,aAwKvB,OAAOitB,GAET,GAAIkB,EAAetX,UAAU7W,SAzKA,iBA0K3B,MA5JsB,MA8JxB,GAAImuB,EAAetX,UAAU7W,SA3KE,mBA4K7B,MA9JyB,SAkK3B,MAAMouB,EAAkF,QAA1E3tB,iBAAiB+a,KAAKkS,OAAOpX,iBAAiB,iBAAiB6K,OAC7E,OAAIgN,EAAetX,UAAU7W,SArLP,UAsLbouB,EAAQvB,GAAmBD,GAE7BwB,EAAQrB,GAAsBD,EACvC,CACA,aAAAc,GACE,OAAkD,OAA3CpS,KAAK4E,SAAS5J,QAnLD,UAoLtB,CACA,UAAA6X,GACE,MAAM,OACJ7qB,GACEgY,KAAK6E,QACT,MAAsB,iBAAX7c,EACFA,EAAO9F,MAAM,KAAKY,KAAInF,GAAS4f,OAAO6P,SAASzvB,EAAO,MAEzC,mBAAXqK,EACF8qB,GAAc9qB,EAAO8qB,EAAY9S,KAAK4E,UAExC5c,CACT,CACA,gBAAAyqB,GACE,MAAMM,EAAwB,CAC5Br0B,UAAWshB,KAAK0S,gBAChBtc,UAAW,CAAC,CACV9V,KAAM,kBACNmB,QAAS,CACPwM,SAAU+R,KAAK6E,QAAQ5W,WAExB,CACD3N,KAAM,SACNmB,QAAS,CACPuG,OAAQgY,KAAK6S,iBAanB,OAPI7S,KAAKmS,WAAsC,WAAzBnS,KAAK6E,QAAQ+M,WACjC5O,GAAYC,iBAAiBjD,KAAKkS,MAAO,SAAU,UACnDa,EAAsB3c,UAAY,CAAC,CACjC9V,KAAM,cACNC,SAAS,KAGN,IACFwyB,KACAlW,GAAQmD,KAAK6E,QAAQgN,aAAc,CAACkB,IAE3C,CACA,eAAAC,EAAgB,IACdl2B,EAAG,OACHyP,IAEA,MAAM6f,EAAQxG,GAAezT,KAhOF,8DAgO+B6N,KAAKkS,OAAO/rB,QAAO5G,GAAWob,GAAUpb,KAC7F6sB,EAAM1b,QAMXoN,GAAqBsO,EAAO7f,EAAQzP,IAAQ0zB,IAAmBpE,EAAMhL,SAAS7U,IAAS+lB,OACzF,CAGA,sBAAO7V,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO0nB,GAASzM,oBAAoBtF,KAAM8D,GAChD,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,CACA,iBAAOmP,CAAW7T,GAChB,GA5QuB,IA4QnBA,EAAMuI,QAAgD,UAAfvI,EAAMqB,MA/QnC,QA+QuDrB,EAAMtiB,IACzE,OAEF,MAAMo2B,EAActN,GAAezT,KAAK+e,IACxC,IAAK,MAAMxJ,KAAUwL,EAAa,CAChC,MAAMC,EAAUpB,GAAS1M,YAAYqC,GACrC,IAAKyL,IAAyC,IAA9BA,EAAQtO,QAAQ8M,UAC9B,SAEF,MAAMyB,EAAehU,EAAMgU,eACrBC,EAAeD,EAAahS,SAAS+R,EAAQjB,OACnD,GAAIkB,EAAahS,SAAS+R,EAAQvO,WAA2C,WAA9BuO,EAAQtO,QAAQ8M,YAA2B0B,GAA8C,YAA9BF,EAAQtO,QAAQ8M,WAA2B0B,EACnJ,SAIF,GAAIF,EAAQjB,MAAM1tB,SAAS4a,EAAM7S,UAA2B,UAAf6S,EAAMqB,MA/RvC,QA+R2DrB,EAAMtiB,KAAqB,qCAAqCuG,KAAK+b,EAAM7S,OAAOya,UACvJ,SAEF,MAAMlH,EAAgB,CACpBA,cAAeqT,EAAQvO,UAEN,UAAfxF,EAAMqB,OACRX,EAAciH,WAAa3H,GAE7B+T,EAAQZ,cAAczS,EACxB,CACF,CACA,4BAAOwT,CAAsBlU,GAI3B,MAAMmU,EAAU,kBAAkBlwB,KAAK+b,EAAM7S,OAAOya,SAC9CwM,EAjTW,WAiTKpU,EAAMtiB,IACtB22B,EAAkB,CAAClD,GAAgBC,IAAkBpP,SAAShC,EAAMtiB,KAC1E,IAAK22B,IAAoBD,EACvB,OAEF,GAAID,IAAYC,EACd,OAEFpU,EAAMkD,iBAGN,MAAMoR,EAAkB1T,KAAK+F,QAAQkL,IAA0BjR,KAAO4F,GAAeM,KAAKlG,KAAMiR,IAAwB,IAAMrL,GAAe/gB,KAAKmb,KAAMiR,IAAwB,IAAMrL,GAAeC,QAAQoL,GAAwB7R,EAAMW,eAAehb,YACpPwF,EAAWwnB,GAASzM,oBAAoBoO,GAC9C,GAAID,EAIF,OAHArU,EAAMuU,kBACNppB,EAASmlB,YACTnlB,EAASyoB,gBAAgB5T,GAGvB7U,EAASilB,aAEXpQ,EAAMuU,kBACNppB,EAASklB,OACTiE,EAAgBpB,QAEpB,EAOF/R,GAAac,GAAGhc,SAAUyrB,GAAwBG,GAAwBc,GAASuB,uBACnF/S,GAAac,GAAGhc,SAAUyrB,GAAwBK,GAAeY,GAASuB,uBAC1E/S,GAAac,GAAGhc,SAAUwrB,GAAwBkB,GAASkB,YAC3D1S,GAAac,GAAGhc,SAAU0rB,GAAsBgB,GAASkB,YACzD1S,GAAac,GAAGhc,SAAUwrB,GAAwBI,IAAwB,SAAU7R,GAClFA,EAAMkD,iBACNyP,GAASzM,oBAAoBtF,MAAM0H,QACrC,IAMAvL,GAAmB4V,IAcnB,MAAM6B,GAAS,WAETC,GAAoB,OACpBC,GAAkB,gBAAgBF,KAClCG,GAAY,CAChBC,UAAW,iBACXC,cAAe,KACf7O,YAAY,EACZzK,WAAW,EAEXuZ,YAAa,QAGTC,GAAgB,CACpBH,UAAW,SACXC,cAAe,kBACf7O,WAAY,UACZzK,UAAW,UACXuZ,YAAa,oBAOf,MAAME,WAAiB3Q,GACrB,WAAAU,CAAYL,GACVa,QACA3E,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/B9D,KAAKqU,aAAc,EACnBrU,KAAK4E,SAAW,IAClB,CAGA,kBAAWlB,GACT,OAAOqQ,EACT,CACA,sBAAWpQ,GACT,OAAOwQ,EACT,CACA,eAAW5X,GACT,OAAOqX,EACT,CAGA,IAAAlE,CAAKrT,GACH,IAAK2D,KAAK6E,QAAQlK,UAEhB,YADAkC,GAAQR,GAGV2D,KAAKsU,UACL,MAAM/0B,EAAUygB,KAAKuU,cACjBvU,KAAK6E,QAAQO,YACfvJ,GAAOtc,GAETA,EAAQ8b,UAAU5E,IAAIod,IACtB7T,KAAKwU,mBAAkB,KACrB3X,GAAQR,EAAS,GAErB,CACA,IAAAoT,CAAKpT,GACE2D,KAAK6E,QAAQlK,WAIlBqF,KAAKuU,cAAclZ,UAAU1B,OAAOka,IACpC7T,KAAKwU,mBAAkB,KACrBxU,KAAK+E,UACLlI,GAAQR,EAAS,KANjBQ,GAAQR,EAQZ,CACA,OAAA0I,GACO/E,KAAKqU,cAGV9T,GAAaC,IAAIR,KAAK4E,SAAUkP,IAChC9T,KAAK4E,SAASjL,SACdqG,KAAKqU,aAAc,EACrB,CAGA,WAAAE,GACE,IAAKvU,KAAK4E,SAAU,CAClB,MAAM6P,EAAWpvB,SAASqvB,cAAc,OACxCD,EAAST,UAAYhU,KAAK6E,QAAQmP,UAC9BhU,KAAK6E,QAAQO,YACfqP,EAASpZ,UAAU5E,IArFD,QAuFpBuJ,KAAK4E,SAAW6P,CAClB,CACA,OAAOzU,KAAK4E,QACd,CACA,iBAAAZ,CAAkBF,GAGhB,OADAA,EAAOoQ,YAAcxZ,GAAWoJ,EAAOoQ,aAChCpQ,CACT,CACA,OAAAwQ,GACE,GAAItU,KAAKqU,YACP,OAEF,MAAM90B,EAAUygB,KAAKuU,cACrBvU,KAAK6E,QAAQqP,YAAYS,OAAOp1B,GAChCghB,GAAac,GAAG9hB,EAASu0B,IAAiB,KACxCjX,GAAQmD,KAAK6E,QAAQoP,cAAc,IAErCjU,KAAKqU,aAAc,CACrB,CACA,iBAAAG,CAAkBnY,GAChBW,GAAuBX,EAAU2D,KAAKuU,cAAevU,KAAK6E,QAAQO,WACpE,EAeF,MAEMwP,GAAc,gBACdC,GAAkB,UAAUD,KAC5BE,GAAoB,cAAcF,KAGlCG,GAAmB,WACnBC,GAAY,CAChBC,WAAW,EACXC,YAAa,MAGTC,GAAgB,CACpBF,UAAW,UACXC,YAAa,WAOf,MAAME,WAAkB3R,GACtB,WAAAU,CAAYL,GACVa,QACA3E,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/B9D,KAAKqV,WAAY,EACjBrV,KAAKsV,qBAAuB,IAC9B,CAGA,kBAAW5R,GACT,OAAOsR,EACT,CACA,sBAAWrR,GACT,OAAOwR,EACT,CACA,eAAW5Y,GACT,MAtCW,WAuCb,CAGA,QAAAgZ,GACMvV,KAAKqV,YAGLrV,KAAK6E,QAAQoQ,WACfjV,KAAK6E,QAAQqQ,YAAY5C,QAE3B/R,GAAaC,IAAInb,SAAUuvB,IAC3BrU,GAAac,GAAGhc,SAAUwvB,IAAiBzV,GAASY,KAAKwV,eAAepW,KACxEmB,GAAac,GAAGhc,SAAUyvB,IAAmB1V,GAASY,KAAKyV,eAAerW,KAC1EY,KAAKqV,WAAY,EACnB,CACA,UAAAK,GACO1V,KAAKqV,YAGVrV,KAAKqV,WAAY,EACjB9U,GAAaC,IAAInb,SAAUuvB,IAC7B,CAGA,cAAAY,CAAepW,GACb,MAAM,YACJ8V,GACElV,KAAK6E,QACT,GAAIzF,EAAM7S,SAAWlH,UAAY+Z,EAAM7S,SAAW2oB,GAAeA,EAAY1wB,SAAS4a,EAAM7S,QAC1F,OAEF,MAAM1L,EAAW+kB,GAAeU,kBAAkB4O,GAC1B,IAApBr0B,EAAS6P,OACXwkB,EAAY5C,QACHtS,KAAKsV,uBAAyBP,GACvCl0B,EAASA,EAAS6P,OAAS,GAAG4hB,QAE9BzxB,EAAS,GAAGyxB,OAEhB,CACA,cAAAmD,CAAerW,GA1ED,QA2ERA,EAAMtiB,MAGVkjB,KAAKsV,qBAAuBlW,EAAMuW,SAAWZ,GA7EzB,UA8EtB,EAeF,MAAMa,GAAyB,oDACzBC,GAA0B,cAC1BC,GAAmB,gBACnBC,GAAkB,eAMxB,MAAMC,GACJ,WAAA7R,GACEnE,KAAK4E,SAAWvf,SAAS6G,IAC3B,CAGA,QAAA+pB,GAEE,MAAMC,EAAgB7wB,SAASC,gBAAgBuC,YAC/C,OAAO1F,KAAKoC,IAAI3E,OAAOu2B,WAAaD,EACtC,CACA,IAAAzG,GACE,MAAM5rB,EAAQmc,KAAKiW,WACnBjW,KAAKoW,mBAELpW,KAAKqW,sBAAsBrW,KAAK4E,SAAUkR,IAAkBQ,GAAmBA,EAAkBzyB,IAEjGmc,KAAKqW,sBAAsBT,GAAwBE,IAAkBQ,GAAmBA,EAAkBzyB,IAC1Gmc,KAAKqW,sBAAsBR,GAAyBE,IAAiBO,GAAmBA,EAAkBzyB,GAC5G,CACA,KAAAwO,GACE2N,KAAKuW,wBAAwBvW,KAAK4E,SAAU,YAC5C5E,KAAKuW,wBAAwBvW,KAAK4E,SAAUkR,IAC5C9V,KAAKuW,wBAAwBX,GAAwBE,IACrD9V,KAAKuW,wBAAwBV,GAAyBE,GACxD,CACA,aAAAS,GACE,OAAOxW,KAAKiW,WAAa,CAC3B,CAGA,gBAAAG,GACEpW,KAAKyW,sBAAsBzW,KAAK4E,SAAU,YAC1C5E,KAAK4E,SAAS7jB,MAAM+K,SAAW,QACjC,CACA,qBAAAuqB,CAAsBtc,EAAU2c,EAAera,GAC7C,MAAMsa,EAAiB3W,KAAKiW,WAS5BjW,KAAK4W,2BAA2B7c,GARHxa,IAC3B,GAAIA,IAAYygB,KAAK4E,UAAYhlB,OAAOu2B,WAAa52B,EAAQsI,YAAc8uB,EACzE,OAEF3W,KAAKyW,sBAAsBl3B,EAASm3B,GACpC,MAAMJ,EAAkB12B,OAAOqF,iBAAiB1F,GAASub,iBAAiB4b,GAC1En3B,EAAQwB,MAAM81B,YAAYH,EAAe,GAAGra,EAASkB,OAAOC,WAAW8Y,QAAsB,GAGjG,CACA,qBAAAG,CAAsBl3B,EAASm3B,GAC7B,MAAMI,EAAcv3B,EAAQwB,MAAM+Z,iBAAiB4b,GAC/CI,GACF9T,GAAYC,iBAAiB1jB,EAASm3B,EAAeI,EAEzD,CACA,uBAAAP,CAAwBxc,EAAU2c,GAWhC1W,KAAK4W,2BAA2B7c,GAVHxa,IAC3B,MAAM5B,EAAQqlB,GAAYQ,iBAAiBjkB,EAASm3B,GAEtC,OAAV/4B,GAIJqlB,GAAYE,oBAAoB3jB,EAASm3B,GACzCn3B,EAAQwB,MAAM81B,YAAYH,EAAe/4B,IAJvC4B,EAAQwB,MAAMg2B,eAAeL,EAIgB,GAGnD,CACA,0BAAAE,CAA2B7c,EAAUid,GACnC,GAAI,GAAUjd,GACZid,EAASjd,QAGX,IAAK,MAAMkd,KAAOrR,GAAezT,KAAK4H,EAAUiG,KAAK4E,UACnDoS,EAASC,EAEb,EAeF,MAEMC,GAAc,YAGdC,GAAe,OAAOD,KACtBE,GAAyB,gBAAgBF,KACzCG,GAAiB,SAASH,KAC1BI,GAAe,OAAOJ,KACtBK,GAAgB,QAAQL,KACxBM,GAAiB,SAASN,KAC1BO,GAAsB,gBAAgBP,KACtCQ,GAA0B,oBAAoBR,KAC9CS,GAA0B,kBAAkBT,KAC5CU,GAAyB,QAAQV,cACjCW,GAAkB,aAElBC,GAAoB,OACpBC,GAAoB,eAKpBC,GAAY,CAChBvD,UAAU,EACVnC,OAAO,EACPzH,UAAU,GAENoN,GAAgB,CACpBxD,SAAU,mBACVnC,MAAO,UACPzH,SAAU,WAOZ,MAAMqN,WAAcxT,GAClB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKmY,QAAUvS,GAAeC,QArBV,gBAqBmC7F,KAAK4E,UAC5D5E,KAAKoY,UAAYpY,KAAKqY,sBACtBrY,KAAKsY,WAAatY,KAAKuY,uBACvBvY,KAAKwP,UAAW,EAChBxP,KAAKgP,kBAAmB,EACxBhP,KAAKwY,WAAa,IAAIxC,GACtBhW,KAAK0L,oBACP,CAGA,kBAAWhI,GACT,OAAOsU,EACT,CACA,sBAAWrU,GACT,OAAOsU,EACT,CACA,eAAW1b,GACT,MA1DW,OA2Db,CAGA,MAAAmL,CAAO5H,GACL,OAAOE,KAAKwP,SAAWxP,KAAKyP,OAASzP,KAAK0P,KAAK5P,EACjD,CACA,IAAA4P,CAAK5P,GACCE,KAAKwP,UAAYxP,KAAKgP,kBAGRzO,GAAaqB,QAAQ5B,KAAK4E,SAAU0S,GAAc,CAClExX,kBAEYkC,mBAGdhC,KAAKwP,UAAW,EAChBxP,KAAKgP,kBAAmB,EACxBhP,KAAKwY,WAAW/I,OAChBpqB,SAAS6G,KAAKmP,UAAU5E,IAAIohB,IAC5B7X,KAAKyY,gBACLzY,KAAKoY,UAAU1I,MAAK,IAAM1P,KAAK0Y,aAAa5Y,KAC9C,CACA,IAAA2P,GACOzP,KAAKwP,WAAYxP,KAAKgP,mBAGTzO,GAAaqB,QAAQ5B,KAAK4E,SAAUuS,IACxCnV,mBAGdhC,KAAKwP,UAAW,EAChBxP,KAAKgP,kBAAmB,EACxBhP,KAAKsY,WAAW5C,aAChB1V,KAAK4E,SAASvJ,UAAU1B,OAAOme,IAC/B9X,KAAKmF,gBAAe,IAAMnF,KAAK2Y,cAAc3Y,KAAK4E,SAAU5E,KAAK6N,gBACnE,CACA,OAAA9I,GACExE,GAAaC,IAAI5gB,OAAQs3B,IACzB3W,GAAaC,IAAIR,KAAKmY,QAASjB,IAC/BlX,KAAKoY,UAAUrT,UACf/E,KAAKsY,WAAW5C,aAChB/Q,MAAMI,SACR,CACA,YAAA6T,GACE5Y,KAAKyY,eACP,CAGA,mBAAAJ,GACE,OAAO,IAAIjE,GAAS,CAClBzZ,UAAWmG,QAAQd,KAAK6E,QAAQ4P,UAEhCrP,WAAYpF,KAAK6N,eAErB,CACA,oBAAA0K,GACE,OAAO,IAAInD,GAAU,CACnBF,YAAalV,KAAK4E,UAEtB,CACA,YAAA8T,CAAa5Y,GAENza,SAAS6G,KAAK1H,SAASwb,KAAK4E,WAC/Bvf,SAAS6G,KAAKyoB,OAAO3U,KAAK4E,UAE5B5E,KAAK4E,SAAS7jB,MAAM6wB,QAAU,QAC9B5R,KAAK4E,SAASzjB,gBAAgB,eAC9B6e,KAAK4E,SAASxjB,aAAa,cAAc,GACzC4e,KAAK4E,SAASxjB,aAAa,OAAQ,UACnC4e,KAAK4E,SAASnZ,UAAY,EAC1B,MAAMotB,EAAYjT,GAAeC,QA7GT,cA6GsC7F,KAAKmY,SAC/DU,IACFA,EAAUptB,UAAY,GAExBoQ,GAAOmE,KAAK4E,UACZ5E,KAAK4E,SAASvJ,UAAU5E,IAAIqhB,IAU5B9X,KAAKmF,gBATsB,KACrBnF,KAAK6E,QAAQyN,OACftS,KAAKsY,WAAW/C,WAElBvV,KAAKgP,kBAAmB,EACxBzO,GAAaqB,QAAQ5B,KAAK4E,SAAU2S,GAAe,CACjDzX,iBACA,GAEoCE,KAAKmY,QAASnY,KAAK6N,cAC7D,CACA,kBAAAnC,GACEnL,GAAac,GAAGrB,KAAK4E,SAAU+S,IAAyBvY,IAhJvC,WAiJXA,EAAMtiB,MAGNkjB,KAAK6E,QAAQgG,SACf7K,KAAKyP,OAGPzP,KAAK8Y,6BAA4B,IAEnCvY,GAAac,GAAGzhB,OAAQ43B,IAAgB,KAClCxX,KAAKwP,WAAaxP,KAAKgP,kBACzBhP,KAAKyY,eACP,IAEFlY,GAAac,GAAGrB,KAAK4E,SAAU8S,IAAyBtY,IAEtDmB,GAAae,IAAItB,KAAK4E,SAAU6S,IAAqBsB,IAC/C/Y,KAAK4E,WAAaxF,EAAM7S,QAAUyT,KAAK4E,WAAamU,EAAOxsB,SAGjC,WAA1ByT,KAAK6E,QAAQ4P,SAIbzU,KAAK6E,QAAQ4P,UACfzU,KAAKyP,OAJLzP,KAAK8Y,6BAKP,GACA,GAEN,CACA,UAAAH,GACE3Y,KAAK4E,SAAS7jB,MAAM6wB,QAAU,OAC9B5R,KAAK4E,SAASxjB,aAAa,eAAe,GAC1C4e,KAAK4E,SAASzjB,gBAAgB,cAC9B6e,KAAK4E,SAASzjB,gBAAgB,QAC9B6e,KAAKgP,kBAAmB,EACxBhP,KAAKoY,UAAU3I,MAAK,KAClBpqB,SAAS6G,KAAKmP,UAAU1B,OAAOke,IAC/B7X,KAAKgZ,oBACLhZ,KAAKwY,WAAWnmB,QAChBkO,GAAaqB,QAAQ5B,KAAK4E,SAAUyS,GAAe,GAEvD,CACA,WAAAxJ,GACE,OAAO7N,KAAK4E,SAASvJ,UAAU7W,SAjLT,OAkLxB,CACA,0BAAAs0B,GAEE,GADkBvY,GAAaqB,QAAQ5B,KAAK4E,SAAUwS,IACxCpV,iBACZ,OAEF,MAAMiX,EAAqBjZ,KAAK4E,SAASvX,aAAehI,SAASC,gBAAgBsC,aAC3EsxB,EAAmBlZ,KAAK4E,SAAS7jB,MAAMiL,UAEpB,WAArBktB,GAAiClZ,KAAK4E,SAASvJ,UAAU7W,SAASuzB,MAGjEkB,IACHjZ,KAAK4E,SAAS7jB,MAAMiL,UAAY,UAElCgU,KAAK4E,SAASvJ,UAAU5E,IAAIshB,IAC5B/X,KAAKmF,gBAAe,KAClBnF,KAAK4E,SAASvJ,UAAU1B,OAAOoe,IAC/B/X,KAAKmF,gBAAe,KAClBnF,KAAK4E,SAAS7jB,MAAMiL,UAAYktB,CAAgB,GAC/ClZ,KAAKmY,QAAQ,GACfnY,KAAKmY,SACRnY,KAAK4E,SAAS0N,QAChB,CAMA,aAAAmG,GACE,MAAMQ,EAAqBjZ,KAAK4E,SAASvX,aAAehI,SAASC,gBAAgBsC,aAC3E+uB,EAAiB3W,KAAKwY,WAAWvC,WACjCkD,EAAoBxC,EAAiB,EAC3C,GAAIwC,IAAsBF,EAAoB,CAC5C,MAAMn3B,EAAWma,KAAU,cAAgB,eAC3C+D,KAAK4E,SAAS7jB,MAAMe,GAAY,GAAG60B,KACrC,CACA,IAAKwC,GAAqBF,EAAoB,CAC5C,MAAMn3B,EAAWma,KAAU,eAAiB,cAC5C+D,KAAK4E,SAAS7jB,MAAMe,GAAY,GAAG60B,KACrC,CACF,CACA,iBAAAqC,GACEhZ,KAAK4E,SAAS7jB,MAAMq4B,YAAc,GAClCpZ,KAAK4E,SAAS7jB,MAAMs4B,aAAe,EACrC,CAGA,sBAAO5c,CAAgBqH,EAAQhE,GAC7B,OAAOE,KAAKuH,MAAK,WACf,MAAMld,EAAO6tB,GAAM5S,oBAAoBtF,KAAM8D,GAC7C,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQhE,EAJb,CAKF,GACF,EAOFS,GAAac,GAAGhc,SAAUuyB,GA9OK,4BA8O2C,SAAUxY,GAClF,MAAM7S,EAASqZ,GAAec,uBAAuB1G,MACjD,CAAC,IAAK,QAAQoB,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAER/B,GAAae,IAAI/U,EAAQ+qB,IAAcgC,IACjCA,EAAUtX,kBAIdzB,GAAae,IAAI/U,EAAQ8qB,IAAgB,KACnC1c,GAAUqF,OACZA,KAAKsS,OACP,GACA,IAIJ,MAAMiH,EAAc3T,GAAeC,QAnQb,eAoQlB0T,GACFrB,GAAM7S,YAAYkU,GAAa9J,OAEpByI,GAAM5S,oBAAoB/Y,GAClCmb,OAAO1H,KACd,IACA4G,GAAqBsR,IAMrB/b,GAAmB+b,IAcnB,MAEMsB,GAAc,gBACdC,GAAiB,YACjBC,GAAwB,OAAOF,KAAcC,KAE7CE,GAAoB,OACpBC,GAAuB,UACvBC,GAAoB,SAEpBC,GAAgB,kBAChBC,GAAe,OAAOP,KACtBQ,GAAgB,QAAQR,KACxBS,GAAe,OAAOT,KACtBU,GAAuB,gBAAgBV,KACvCW,GAAiB,SAASX,KAC1BY,GAAe,SAASZ,KACxBa,GAAyB,QAAQb,KAAcC,KAC/Ca,GAAwB,kBAAkBd,KAE1Ce,GAAY,CAChB9F,UAAU,EACV5J,UAAU,EACVpgB,QAAQ,GAEJ+vB,GAAgB,CACpB/F,SAAU,mBACV5J,SAAU,UACVpgB,OAAQ,WAOV,MAAMgwB,WAAkB/V,GACtB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKwP,UAAW,EAChBxP,KAAKoY,UAAYpY,KAAKqY,sBACtBrY,KAAKsY,WAAatY,KAAKuY,uBACvBvY,KAAK0L,oBACP,CAGA,kBAAWhI,GACT,OAAO6W,EACT,CACA,sBAAW5W,GACT,OAAO6W,EACT,CACA,eAAWje,GACT,MApDW,WAqDb,CAGA,MAAAmL,CAAO5H,GACL,OAAOE,KAAKwP,SAAWxP,KAAKyP,OAASzP,KAAK0P,KAAK5P,EACjD,CACA,IAAA4P,CAAK5P,GACCE,KAAKwP,UAGSjP,GAAaqB,QAAQ5B,KAAK4E,SAAUmV,GAAc,CAClEja,kBAEYkC,mBAGdhC,KAAKwP,UAAW,EAChBxP,KAAKoY,UAAU1I,OACV1P,KAAK6E,QAAQpa,SAChB,IAAIurB,IAAkBvG,OAExBzP,KAAK4E,SAASxjB,aAAa,cAAc,GACzC4e,KAAK4E,SAASxjB,aAAa,OAAQ,UACnC4e,KAAK4E,SAASvJ,UAAU5E,IAAImjB,IAW5B5Z,KAAKmF,gBAVoB,KAClBnF,KAAK6E,QAAQpa,SAAUuV,KAAK6E,QAAQ4P,UACvCzU,KAAKsY,WAAW/C,WAElBvV,KAAK4E,SAASvJ,UAAU5E,IAAIkjB,IAC5B3Z,KAAK4E,SAASvJ,UAAU1B,OAAOigB,IAC/BrZ,GAAaqB,QAAQ5B,KAAK4E,SAAUoV,GAAe,CACjDla,iBACA,GAEkCE,KAAK4E,UAAU,GACvD,CACA,IAAA6K,GACOzP,KAAKwP,WAGQjP,GAAaqB,QAAQ5B,KAAK4E,SAAUqV,IACxCjY,mBAGdhC,KAAKsY,WAAW5C,aAChB1V,KAAK4E,SAAS8V,OACd1a,KAAKwP,UAAW,EAChBxP,KAAK4E,SAASvJ,UAAU5E,IAAIojB,IAC5B7Z,KAAKoY,UAAU3I,OAUfzP,KAAKmF,gBAToB,KACvBnF,KAAK4E,SAASvJ,UAAU1B,OAAOggB,GAAmBE,IAClD7Z,KAAK4E,SAASzjB,gBAAgB,cAC9B6e,KAAK4E,SAASzjB,gBAAgB,QACzB6e,KAAK6E,QAAQpa,SAChB,IAAIurB,IAAkB3jB,QAExBkO,GAAaqB,QAAQ5B,KAAK4E,SAAUuV,GAAe,GAEfna,KAAK4E,UAAU,IACvD,CACA,OAAAG,GACE/E,KAAKoY,UAAUrT,UACf/E,KAAKsY,WAAW5C,aAChB/Q,MAAMI,SACR,CAGA,mBAAAsT,GACE,MASM1d,EAAYmG,QAAQd,KAAK6E,QAAQ4P,UACvC,OAAO,IAAIL,GAAS,CAClBJ,UA3HsB,qBA4HtBrZ,YACAyK,YAAY,EACZ8O,YAAalU,KAAK4E,SAAS7f,WAC3BkvB,cAAetZ,EAfK,KACU,WAA1BqF,KAAK6E,QAAQ4P,SAIjBzU,KAAKyP,OAHHlP,GAAaqB,QAAQ5B,KAAK4E,SAAUsV,GAG3B,EAUgC,MAE/C,CACA,oBAAA3B,GACE,OAAO,IAAInD,GAAU,CACnBF,YAAalV,KAAK4E,UAEtB,CACA,kBAAA8G,GACEnL,GAAac,GAAGrB,KAAK4E,SAAU0V,IAAuBlb,IA5IvC,WA6ITA,EAAMtiB,MAGNkjB,KAAK6E,QAAQgG,SACf7K,KAAKyP,OAGPlP,GAAaqB,QAAQ5B,KAAK4E,SAAUsV,IAAqB,GAE7D,CAGA,sBAAOzd,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOowB,GAAUnV,oBAAoBtF,KAAM8D,GACjD,GAAsB,iBAAXA,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQ9D,KAJb,CAKF,GACF,EAOFO,GAAac,GAAGhc,SAAUg1B,GA7JK,gCA6J2C,SAAUjb,GAClF,MAAM7S,EAASqZ,GAAec,uBAAuB1G,MAIrD,GAHI,CAAC,IAAK,QAAQoB,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAEJpH,GAAW8E,MACb,OAEFO,GAAae,IAAI/U,EAAQ4tB,IAAgB,KAEnCxf,GAAUqF,OACZA,KAAKsS,OACP,IAIF,MAAMiH,EAAc3T,GAAeC,QAAQiU,IACvCP,GAAeA,IAAgBhtB,GACjCkuB,GAAUpV,YAAYkU,GAAa9J,OAExBgL,GAAUnV,oBAAoB/Y,GACtCmb,OAAO1H,KACd,IACAO,GAAac,GAAGzhB,OAAQ85B,IAAuB,KAC7C,IAAK,MAAM3f,KAAY6L,GAAezT,KAAK2nB,IACzCW,GAAUnV,oBAAoBvL,GAAU2V,MAC1C,IAEFnP,GAAac,GAAGzhB,OAAQw6B,IAAc,KACpC,IAAK,MAAM76B,KAAWqmB,GAAezT,KAAK,gDACG,UAAvClN,iBAAiB1F,GAASiC,UAC5Bi5B,GAAUnV,oBAAoB/lB,GAASkwB,MAE3C,IAEF7I,GAAqB6T,IAMrBte,GAAmBse,IAUnB,MACME,GAAmB,CAEvB,IAAK,CAAC,QAAS,MAAO,KAAM,OAAQ,OAHP,kBAI7B9pB,EAAG,CAAC,SAAU,OAAQ,QAAS,OAC/B+pB,KAAM,GACN9pB,EAAG,GACH+pB,GAAI,GACJC,IAAK,GACLC,KAAM,GACNC,IAAK,GACLC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJnqB,EAAG,GACHub,IAAK,CAAC,MAAO,SAAU,MAAO,QAAS,QAAS,UAChD6O,GAAI,GACJC,GAAI,GACJC,EAAG,GACHC,IAAK,GACLC,EAAG,GACHC,MAAO,GACPC,KAAM,GACNC,IAAK,GACLC,IAAK,GACLC,OAAQ,GACRC,EAAG,GACHC,GAAI,IAIAC,GAAgB,IAAI/lB,IAAI,CAAC,aAAc,OAAQ,OAAQ,WAAY,WAAY,SAAU,MAAO,eAShGgmB,GAAmB,0DACnBC,GAAmB,CAACx6B,EAAWy6B,KACnC,MAAMC,EAAgB16B,EAAUvC,SAASC,cACzC,OAAI+8B,EAAqBpb,SAASqb,IAC5BJ,GAAc1lB,IAAI8lB,IACb3b,QAAQwb,GAAiBj5B,KAAKtB,EAAU26B,YAM5CF,EAAqBr2B,QAAOw2B,GAAkBA,aAA0BpY,SAAQ9R,MAAKmqB,GAASA,EAAMv5B,KAAKo5B,IAAe,EA0C3HI,GAAY,CAChBC,UAAWnC,GACXoC,QAAS,CAAC,EAEVC,WAAY,GACZnwB,MAAM,EACNowB,UAAU,EACVC,WAAY,KACZC,SAAU,eAENC,GAAgB,CACpBN,UAAW,SACXC,QAAS,SACTC,WAAY,oBACZnwB,KAAM,UACNowB,SAAU,UACVC,WAAY,kBACZC,SAAU,UAENE,GAAqB,CACzBC,MAAO,iCACPvjB,SAAU,oBAOZ,MAAMwjB,WAAwB9Z,GAC5B,WAAAU,CAAYL,GACVa,QACA3E,KAAK6E,QAAU7E,KAAK6D,WAAWC,EACjC,CAGA,kBAAWJ,GACT,OAAOmZ,EACT,CACA,sBAAWlZ,GACT,OAAOyZ,EACT,CACA,eAAW7gB,GACT,MA3CW,iBA4Cb,CAGA,UAAAihB,GACE,OAAOxgC,OAAOmiB,OAAOa,KAAK6E,QAAQkY,SAASj6B,KAAIghB,GAAU9D,KAAKyd,yBAAyB3Z,KAAS3d,OAAO2a,QACzG,CACA,UAAA4c,GACE,OAAO1d,KAAKwd,aAAa9sB,OAAS,CACpC,CACA,aAAAitB,CAAcZ,GAMZ,OALA/c,KAAK4d,cAAcb,GACnB/c,KAAK6E,QAAQkY,QAAU,IAClB/c,KAAK6E,QAAQkY,WACbA,GAEE/c,IACT,CACA,MAAA6d,GACE,MAAMC,EAAkBz4B,SAASqvB,cAAc,OAC/CoJ,EAAgBC,UAAY/d,KAAKge,eAAehe,KAAK6E,QAAQsY,UAC7D,IAAK,MAAOpjB,EAAUkkB,KAASjhC,OAAOmkB,QAAQnB,KAAK6E,QAAQkY,SACzD/c,KAAKke,YAAYJ,EAAiBG,EAAMlkB,GAE1C,MAAMojB,EAAWW,EAAgBhY,SAAS,GACpCkX,EAAahd,KAAKyd,yBAAyBzd,KAAK6E,QAAQmY,YAI9D,OAHIA,GACFG,EAAS9hB,UAAU5E,OAAOumB,EAAW96B,MAAM,MAEtCi7B,CACT,CAGA,gBAAAlZ,CAAiBH,GACfa,MAAMV,iBAAiBH,GACvB9D,KAAK4d,cAAc9Z,EAAOiZ,QAC5B,CACA,aAAAa,CAAcO,GACZ,IAAK,MAAOpkB,EAAUgjB,KAAY//B,OAAOmkB,QAAQgd,GAC/CxZ,MAAMV,iBAAiB,CACrBlK,WACAujB,MAAOP,GACNM,GAEP,CACA,WAAAa,CAAYf,EAAUJ,EAAShjB,GAC7B,MAAMqkB,EAAkBxY,GAAeC,QAAQ9L,EAAUojB,GACpDiB,KAGLrB,EAAU/c,KAAKyd,yBAAyBV,IAKpC,GAAUA,GACZ/c,KAAKqe,sBAAsB3jB,GAAWqiB,GAAUqB,GAG9Cpe,KAAK6E,QAAQhY,KACfuxB,EAAgBL,UAAY/d,KAAKge,eAAejB,GAGlDqB,EAAgBE,YAAcvB,EAX5BqB,EAAgBzkB,SAYpB,CACA,cAAAqkB,CAAeG,GACb,OAAOne,KAAK6E,QAAQoY,SApJxB,SAAsBsB,EAAYzB,EAAW0B,GAC3C,IAAKD,EAAW7tB,OACd,OAAO6tB,EAET,GAAIC,GAAgD,mBAArBA,EAC7B,OAAOA,EAAiBD,GAE1B,MACME,GADY,IAAI7+B,OAAO8+B,WACKC,gBAAgBJ,EAAY,aACxD19B,EAAW,GAAGlC,UAAU8/B,EAAgBvyB,KAAKkU,iBAAiB,MACpE,IAAK,MAAM7gB,KAAWsB,EAAU,CAC9B,MAAM+9B,EAAcr/B,EAAQC,SAASC,cACrC,IAAKzC,OAAO4D,KAAKk8B,GAAW1b,SAASwd,GAAc,CACjDr/B,EAAQoa,SACR,QACF,CACA,MAAMklB,EAAgB,GAAGlgC,UAAUY,EAAQ0B,YACrC69B,EAAoB,GAAGngC,OAAOm+B,EAAU,MAAQ,GAAIA,EAAU8B,IAAgB,IACpF,IAAK,MAAM78B,KAAa88B,EACjBtC,GAAiBx6B,EAAW+8B,IAC/Bv/B,EAAQ4B,gBAAgBY,EAAUvC,SAGxC,CACA,OAAOi/B,EAAgBvyB,KAAK6xB,SAC9B,CA2HmCgB,CAAaZ,EAAKne,KAAK6E,QAAQiY,UAAW9c,KAAK6E,QAAQqY,YAAciB,CACtG,CACA,wBAAAV,CAAyBU,GACvB,OAAOthB,GAAQshB,EAAK,CAACne,MACvB,CACA,qBAAAqe,CAAsB9+B,EAAS6+B,GAC7B,GAAIpe,KAAK6E,QAAQhY,KAGf,OAFAuxB,EAAgBL,UAAY,QAC5BK,EAAgBzJ,OAAOp1B,GAGzB6+B,EAAgBE,YAAc/+B,EAAQ++B,WACxC,EAeF,MACMU,GAAwB,IAAI1oB,IAAI,CAAC,WAAY,YAAa,eAC1D2oB,GAAoB,OAEpBC,GAAoB,OAEpBC,GAAiB,SACjBC,GAAmB,gBACnBC,GAAgB,QAChBC,GAAgB,QAahBC,GAAgB,CACpBC,KAAM,OACNC,IAAK,MACLC,MAAOzjB,KAAU,OAAS,QAC1B0jB,OAAQ,SACRC,KAAM3jB,KAAU,QAAU,QAEtB4jB,GAAY,CAChB/C,UAAWnC,GACXmF,WAAW,EACX7xB,SAAU,kBACV8xB,WAAW,EACXC,YAAa,GACbC,MAAO,EACPjwB,mBAAoB,CAAC,MAAO,QAAS,SAAU,QAC/CnD,MAAM,EACN7E,OAAQ,CAAC,EAAG,GACZtJ,UAAW,MACXmzB,aAAc,KACdoL,UAAU,EACVC,WAAY,KACZnjB,UAAU,EACVojB,SAAU,+GACV+C,MAAO,GACPte,QAAS,eAELue,GAAgB,CACpBrD,UAAW,SACXgD,UAAW,UACX7xB,SAAU,mBACV8xB,UAAW,2BACXC,YAAa,oBACbC,MAAO,kBACPjwB,mBAAoB,QACpBnD,KAAM,UACN7E,OAAQ,0BACRtJ,UAAW,oBACXmzB,aAAc,yBACdoL,SAAU,UACVC,WAAY,kBACZnjB,SAAU,mBACVojB,SAAU,SACV+C,MAAO,4BACPte,QAAS,UAOX,MAAMwe,WAAgB1b,GACpB,WAAAP,CAAY5kB,EAASukB,GACnB,QAAsB,IAAX,EACT,MAAM,IAAIU,UAAU,+DAEtBG,MAAMplB,EAASukB,GAGf9D,KAAKqgB,YAAa,EAClBrgB,KAAKsgB,SAAW,EAChBtgB,KAAKugB,WAAa,KAClBvgB,KAAKwgB,eAAiB,CAAC,EACvBxgB,KAAKgS,QAAU,KACfhS,KAAKygB,iBAAmB,KACxBzgB,KAAK0gB,YAAc,KAGnB1gB,KAAK2gB,IAAM,KACX3gB,KAAK4gB,gBACA5gB,KAAK6E,QAAQ9K,UAChBiG,KAAK6gB,WAET,CAGA,kBAAWnd,GACT,OAAOmc,EACT,CACA,sBAAWlc,GACT,OAAOwc,EACT,CACA,eAAW5jB,GACT,MAxGW,SAyGb,CAGA,MAAAukB,GACE9gB,KAAKqgB,YAAa,CACpB,CACA,OAAAU,GACE/gB,KAAKqgB,YAAa,CACpB,CACA,aAAAW,GACEhhB,KAAKqgB,YAAcrgB,KAAKqgB,UAC1B,CACA,MAAA3Y,GACO1H,KAAKqgB,aAGVrgB,KAAKwgB,eAAeS,OAASjhB,KAAKwgB,eAAeS,MAC7CjhB,KAAKwP,WACPxP,KAAKkhB,SAGPlhB,KAAKmhB,SACP,CACA,OAAApc,GACEgI,aAAa/M,KAAKsgB,UAClB/f,GAAaC,IAAIR,KAAK4E,SAAS5J,QAAQmkB,IAAiBC,GAAkBpf,KAAKohB,mBAC3EphB,KAAK4E,SAASpJ,aAAa,2BAC7BwE,KAAK4E,SAASxjB,aAAa,QAAS4e,KAAK4E,SAASpJ,aAAa,2BAEjEwE,KAAKqhB,iBACL1c,MAAMI,SACR,CACA,IAAA2K,GACE,GAAoC,SAAhC1P,KAAK4E,SAAS7jB,MAAM6wB,QACtB,MAAM,IAAIhO,MAAM,uCAElB,IAAM5D,KAAKshB,mBAAoBthB,KAAKqgB,WAClC,OAEF,MAAM/G,EAAY/Y,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAlItD,SAoIX+b,GADa9lB,GAAeuE,KAAK4E,WACL5E,KAAK4E,SAAS9kB,cAAcwF,iBAAiBd,SAASwb,KAAK4E,UAC7F,GAAI0U,EAAUtX,mBAAqBuf,EACjC,OAIFvhB,KAAKqhB,iBACL,MAAMV,EAAM3gB,KAAKwhB,iBACjBxhB,KAAK4E,SAASxjB,aAAa,mBAAoBu/B,EAAInlB,aAAa,OAChE,MAAM,UACJukB,GACE/f,KAAK6E,QAYT,GAXK7E,KAAK4E,SAAS9kB,cAAcwF,gBAAgBd,SAASwb,KAAK2gB,OAC7DZ,EAAUpL,OAAOgM,GACjBpgB,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAhJpC,cAkJnBxF,KAAKgS,QAAUhS,KAAKqS,cAAcsO,GAClCA,EAAItlB,UAAU5E,IAAIyoB,IAMd,iBAAkB75B,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAac,GAAG9hB,EAAS,YAAaqc,IAU1CoE,KAAKmF,gBAPY,KACf5E,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAhKrC,WAiKQ,IAApBxF,KAAKugB,YACPvgB,KAAKkhB,SAEPlhB,KAAKugB,YAAa,CAAK,GAEKvgB,KAAK2gB,IAAK3gB,KAAK6N,cAC/C,CACA,IAAA4B,GACE,GAAKzP,KAAKwP,aAGQjP,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UA/KtD,SAgLHxD,iBAAd,CAQA,GALYhC,KAAKwhB,iBACbnmB,UAAU1B,OAAOulB,IAIjB,iBAAkB75B,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAaC,IAAIjhB,EAAS,YAAaqc,IAG3CoE,KAAKwgB,eAA4B,OAAI,EACrCxgB,KAAKwgB,eAAelB,KAAiB,EACrCtf,KAAKwgB,eAAenB,KAAiB,EACrCrf,KAAKugB,WAAa,KAYlBvgB,KAAKmF,gBAVY,KACXnF,KAAKyhB,yBAGJzhB,KAAKugB,YACRvgB,KAAKqhB,iBAEPrhB,KAAK4E,SAASzjB,gBAAgB,oBAC9Bof,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAzMpC,WAyM8D,GAEnDxF,KAAK2gB,IAAK3gB,KAAK6N,cA1B7C,CA2BF,CACA,MAAA9iB,GACMiV,KAAKgS,SACPhS,KAAKgS,QAAQjnB,QAEjB,CAGA,cAAAu2B,GACE,OAAOxgB,QAAQd,KAAK0hB,YACtB,CACA,cAAAF,GAIE,OAHKxhB,KAAK2gB,MACR3gB,KAAK2gB,IAAM3gB,KAAK2hB,kBAAkB3hB,KAAK0gB,aAAe1gB,KAAK4hB,2BAEtD5hB,KAAK2gB,GACd,CACA,iBAAAgB,CAAkB5E,GAChB,MAAM4D,EAAM3gB,KAAK6hB,oBAAoB9E,GAASc,SAG9C,IAAK8C,EACH,OAAO,KAETA,EAAItlB,UAAU1B,OAAOslB,GAAmBC,IAExCyB,EAAItlB,UAAU5E,IAAI,MAAMuJ,KAAKmE,YAAY5H,aACzC,MAAMulB,EAvuGKC,KACb,GACEA,GAAU5/B,KAAK6/B,MA/BH,IA+BS7/B,KAAK8/B,gBACnB58B,SAAS68B,eAAeH,IACjC,OAAOA,CAAM,EAmuGGI,CAAOniB,KAAKmE,YAAY5H,MAAM1c,WAK5C,OAJA8gC,EAAIv/B,aAAa,KAAM0gC,GACnB9hB,KAAK6N,eACP8S,EAAItlB,UAAU5E,IAAIwoB,IAEb0B,CACT,CACA,UAAAyB,CAAWrF,GACT/c,KAAK0gB,YAAc3D,EACf/c,KAAKwP,aACPxP,KAAKqhB,iBACLrhB,KAAK0P,OAET,CACA,mBAAAmS,CAAoB9E,GAYlB,OAXI/c,KAAKygB,iBACPzgB,KAAKygB,iBAAiB9C,cAAcZ,GAEpC/c,KAAKygB,iBAAmB,IAAIlD,GAAgB,IACvCvd,KAAK6E,QAGRkY,UACAC,WAAYhd,KAAKyd,yBAAyBzd,KAAK6E,QAAQmb,eAGpDhgB,KAAKygB,gBACd,CACA,sBAAAmB,GACE,MAAO,CACL,iBAA0B5hB,KAAK0hB,YAEnC,CACA,SAAAA,GACE,OAAO1hB,KAAKyd,yBAAyBzd,KAAK6E,QAAQqb,QAAUlgB,KAAK4E,SAASpJ,aAAa,yBACzF,CAGA,4BAAA6mB,CAA6BjjB,GAC3B,OAAOY,KAAKmE,YAAYmB,oBAAoBlG,EAAMW,eAAgBC,KAAKsiB,qBACzE,CACA,WAAAzU,GACE,OAAO7N,KAAK6E,QAAQib,WAAa9f,KAAK2gB,KAAO3gB,KAAK2gB,IAAItlB,UAAU7W,SAASy6B,GAC3E,CACA,QAAAzP,GACE,OAAOxP,KAAK2gB,KAAO3gB,KAAK2gB,IAAItlB,UAAU7W,SAAS06B,GACjD,CACA,aAAA7M,CAAcsO,GACZ,MAAMjiC,EAAYme,GAAQmD,KAAK6E,QAAQnmB,UAAW,CAACshB,KAAM2gB,EAAK3gB,KAAK4E,WAC7D2d,EAAahD,GAAc7gC,EAAU+lB,eAC3C,OAAO,GAAoBzE,KAAK4E,SAAU+b,EAAK3gB,KAAKyS,iBAAiB8P,GACvE,CACA,UAAA1P,GACE,MAAM,OACJ7qB,GACEgY,KAAK6E,QACT,MAAsB,iBAAX7c,EACFA,EAAO9F,MAAM,KAAKY,KAAInF,GAAS4f,OAAO6P,SAASzvB,EAAO,MAEzC,mBAAXqK,EACF8qB,GAAc9qB,EAAO8qB,EAAY9S,KAAK4E,UAExC5c,CACT,CACA,wBAAAy1B,CAAyBU,GACvB,OAAOthB,GAAQshB,EAAK,CAACne,KAAK4E,UAC5B,CACA,gBAAA6N,CAAiB8P,GACf,MAAMxP,EAAwB,CAC5Br0B,UAAW6jC,EACXnsB,UAAW,CAAC,CACV9V,KAAM,OACNmB,QAAS,CACPuO,mBAAoBgQ,KAAK6E,QAAQ7U,qBAElC,CACD1P,KAAM,SACNmB,QAAS,CACPuG,OAAQgY,KAAK6S,eAEd,CACDvyB,KAAM,kBACNmB,QAAS,CACPwM,SAAU+R,KAAK6E,QAAQ5W,WAExB,CACD3N,KAAM,QACNmB,QAAS,CACPlC,QAAS,IAAIygB,KAAKmE,YAAY5H,eAE/B,CACDjc,KAAM,kBACNC,SAAS,EACTC,MAAO,aACPC,GAAI4J,IAGF2V,KAAKwhB,iBAAiBpgC,aAAa,wBAAyBiJ,EAAK1J,MAAMjC,UAAU,KAIvF,MAAO,IACFq0B,KACAlW,GAAQmD,KAAK6E,QAAQgN,aAAc,CAACkB,IAE3C,CACA,aAAA6N,GACE,MAAM4B,EAAWxiB,KAAK6E,QAAQjD,QAAQ1f,MAAM,KAC5C,IAAK,MAAM0f,KAAW4gB,EACpB,GAAgB,UAAZ5gB,EACFrB,GAAac,GAAGrB,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAjVlC,SAiV4DxF,KAAK6E,QAAQ9K,UAAUqF,IAC/EY,KAAKqiB,6BAA6BjjB,GAC1CsI,QAAQ,SAEb,GA3VU,WA2VN9F,EAA4B,CACrC,MAAM6gB,EAAU7gB,IAAYyd,GAAgBrf,KAAKmE,YAAYqB,UAnV5C,cAmV0ExF,KAAKmE,YAAYqB,UArV5F,WAsVVkd,EAAW9gB,IAAYyd,GAAgBrf,KAAKmE,YAAYqB,UAnV7C,cAmV2ExF,KAAKmE,YAAYqB,UArV5F,YAsVjBjF,GAAac,GAAGrB,KAAK4E,SAAU6d,EAASziB,KAAK6E,QAAQ9K,UAAUqF,IAC7D,MAAM+T,EAAUnT,KAAKqiB,6BAA6BjjB,GAClD+T,EAAQqN,eAA8B,YAAfphB,EAAMqB,KAAqB6e,GAAgBD,KAAiB,EACnFlM,EAAQgO,QAAQ,IAElB5gB,GAAac,GAAGrB,KAAK4E,SAAU8d,EAAU1iB,KAAK6E,QAAQ9K,UAAUqF,IAC9D,MAAM+T,EAAUnT,KAAKqiB,6BAA6BjjB,GAClD+T,EAAQqN,eAA8B,aAAfphB,EAAMqB,KAAsB6e,GAAgBD,IAAiBlM,EAAQvO,SAASpgB,SAAS4a,EAAMU,eACpHqT,EAAQ+N,QAAQ,GAEpB,CAEFlhB,KAAKohB,kBAAoB,KACnBphB,KAAK4E,UACP5E,KAAKyP,MACP,EAEFlP,GAAac,GAAGrB,KAAK4E,SAAS5J,QAAQmkB,IAAiBC,GAAkBpf,KAAKohB,kBAChF,CACA,SAAAP,GACE,MAAMX,EAAQlgB,KAAK4E,SAASpJ,aAAa,SACpC0kB,IAGAlgB,KAAK4E,SAASpJ,aAAa,eAAkBwE,KAAK4E,SAAS0Z,YAAY3Y,QAC1E3F,KAAK4E,SAASxjB,aAAa,aAAc8+B,GAE3ClgB,KAAK4E,SAASxjB,aAAa,yBAA0B8+B,GACrDlgB,KAAK4E,SAASzjB,gBAAgB,SAChC,CACA,MAAAggC,GACMnhB,KAAKwP,YAAcxP,KAAKugB,WAC1BvgB,KAAKugB,YAAa,GAGpBvgB,KAAKugB,YAAa,EAClBvgB,KAAK2iB,aAAY,KACX3iB,KAAKugB,YACPvgB,KAAK0P,MACP,GACC1P,KAAK6E,QAAQob,MAAMvQ,MACxB,CACA,MAAAwR,GACMlhB,KAAKyhB,yBAGTzhB,KAAKugB,YAAa,EAClBvgB,KAAK2iB,aAAY,KACV3iB,KAAKugB,YACRvgB,KAAKyP,MACP,GACCzP,KAAK6E,QAAQob,MAAMxQ,MACxB,CACA,WAAAkT,CAAY/kB,EAASglB,GACnB7V,aAAa/M,KAAKsgB,UAClBtgB,KAAKsgB,SAAWziB,WAAWD,EAASglB,EACtC,CACA,oBAAAnB,GACE,OAAOzkC,OAAOmiB,OAAOa,KAAKwgB,gBAAgBpf,UAAS,EACrD,CACA,UAAAyC,CAAWC,GACT,MAAM+e,EAAiB7f,GAAYG,kBAAkBnD,KAAK4E,UAC1D,IAAK,MAAMke,KAAiB9lC,OAAO4D,KAAKiiC,GAClC7D,GAAsBroB,IAAImsB,WACrBD,EAAeC,GAU1B,OAPAhf,EAAS,IACJ+e,KACmB,iBAAX/e,GAAuBA,EAASA,EAAS,CAAC,GAEvDA,EAAS9D,KAAK+D,gBAAgBD,GAC9BA,EAAS9D,KAAKgE,kBAAkBF,GAChC9D,KAAKiE,iBAAiBH,GACfA,CACT,CACA,iBAAAE,CAAkBF,GAchB,OAbAA,EAAOic,WAAiC,IAArBjc,EAAOic,UAAsB16B,SAAS6G,KAAOwO,GAAWoJ,EAAOic,WACtD,iBAAjBjc,EAAOmc,QAChBnc,EAAOmc,MAAQ,CACbvQ,KAAM5L,EAAOmc,MACbxQ,KAAM3L,EAAOmc,QAGW,iBAAjBnc,EAAOoc,QAChBpc,EAAOoc,MAAQpc,EAAOoc,MAAMrgC,YAEA,iBAAnBikB,EAAOiZ,UAChBjZ,EAAOiZ,QAAUjZ,EAAOiZ,QAAQl9B,YAE3BikB,CACT,CACA,kBAAAwe,GACE,MAAMxe,EAAS,CAAC,EAChB,IAAK,MAAOhnB,EAAKa,KAAUX,OAAOmkB,QAAQnB,KAAK6E,SACzC7E,KAAKmE,YAAYT,QAAQ5mB,KAASa,IACpCmmB,EAAOhnB,GAAOa,GASlB,OANAmmB,EAAO/J,UAAW,EAClB+J,EAAOlC,QAAU,SAKVkC,CACT,CACA,cAAAud,GACMrhB,KAAKgS,UACPhS,KAAKgS,QAAQhZ,UACbgH,KAAKgS,QAAU,MAEbhS,KAAK2gB,MACP3gB,KAAK2gB,IAAIhnB,SACTqG,KAAK2gB,IAAM,KAEf,CAGA,sBAAOlkB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO+1B,GAAQ9a,oBAAoBtF,KAAM8D,GAC/C,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOF3H,GAAmBikB,IAcnB,MAGM2C,GAAY,IACb3C,GAAQ1c,QACXqZ,QAAS,GACT/0B,OAAQ,CAAC,EAAG,GACZtJ,UAAW,QACXy+B,SAAU,8IACVvb,QAAS,SAELohB,GAAgB,IACjB5C,GAAQzc,YACXoZ,QAAS,kCAOX,MAAMkG,WAAgB7C,GAEpB,kBAAW1c,GACT,OAAOqf,EACT,CACA,sBAAWpf,GACT,OAAOqf,EACT,CACA,eAAWzmB,GACT,MA7BW,SA8Bb,CAGA,cAAA+kB,GACE,OAAOthB,KAAK0hB,aAAe1hB,KAAKkjB,aAClC,CAGA,sBAAAtB,GACE,MAAO,CACL,kBAAkB5hB,KAAK0hB,YACvB,gBAAoB1hB,KAAKkjB,cAE7B,CACA,WAAAA,GACE,OAAOljB,KAAKyd,yBAAyBzd,KAAK6E,QAAQkY,QACpD,CAGA,sBAAOtgB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO44B,GAAQ3d,oBAAoBtF,KAAM8D,GAC/C,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOF3H,GAAmB8mB,IAcnB,MAEME,GAAc,gBAEdC,GAAiB,WAAWD,KAC5BE,GAAc,QAAQF,KACtBG,GAAwB,OAAOH,cAE/BI,GAAsB,SAEtBC,GAAwB,SAExBC,GAAqB,YAGrBC,GAAsB,GAAGD,mBAA+CA,uBAGxEE,GAAY,CAChB37B,OAAQ,KAER47B,WAAY,eACZC,cAAc,EACdt3B,OAAQ,KACRu3B,UAAW,CAAC,GAAK,GAAK,IAElBC,GAAgB,CACpB/7B,OAAQ,gBAER47B,WAAY,SACZC,aAAc,UACdt3B,OAAQ,UACRu3B,UAAW,SAOb,MAAME,WAAkBtf,GACtB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GAGf9D,KAAKikB,aAAe,IAAI/yB,IACxB8O,KAAKkkB,oBAAsB,IAAIhzB,IAC/B8O,KAAKmkB,aAA6D,YAA9Cl/B,iBAAiB+a,KAAK4E,UAAU5Y,UAA0B,KAAOgU,KAAK4E,SAC1F5E,KAAKokB,cAAgB,KACrBpkB,KAAKqkB,UAAY,KACjBrkB,KAAKskB,oBAAsB,CACzBC,gBAAiB,EACjBC,gBAAiB,GAEnBxkB,KAAKykB,SACP,CAGA,kBAAW/gB,GACT,OAAOigB,EACT,CACA,sBAAWhgB,GACT,OAAOogB,EACT,CACA,eAAWxnB,GACT,MAhEW,WAiEb,CAGA,OAAAkoB,GACEzkB,KAAK0kB,mCACL1kB,KAAK2kB,2BACD3kB,KAAKqkB,UACPrkB,KAAKqkB,UAAUO,aAEf5kB,KAAKqkB,UAAYrkB,KAAK6kB,kBAExB,IAAK,MAAMC,KAAW9kB,KAAKkkB,oBAAoB/kB,SAC7Ca,KAAKqkB,UAAUU,QAAQD,EAE3B,CACA,OAAA/f,GACE/E,KAAKqkB,UAAUO,aACfjgB,MAAMI,SACR,CAGA,iBAAAf,CAAkBF,GAShB,OAPAA,EAAOvX,OAASmO,GAAWoJ,EAAOvX,SAAWlH,SAAS6G,KAGtD4X,EAAO8f,WAAa9f,EAAO9b,OAAS,GAAG8b,EAAO9b,oBAAsB8b,EAAO8f,WAC3C,iBAArB9f,EAAOggB,YAChBhgB,EAAOggB,UAAYhgB,EAAOggB,UAAU5hC,MAAM,KAAKY,KAAInF,GAAS4f,OAAOC,WAAW7f,MAEzEmmB,CACT,CACA,wBAAA6gB,GACO3kB,KAAK6E,QAAQgf,eAKlBtjB,GAAaC,IAAIR,KAAK6E,QAAQtY,OAAQ82B,IACtC9iB,GAAac,GAAGrB,KAAK6E,QAAQtY,OAAQ82B,GAAaG,IAAuBpkB,IACvE,MAAM4lB,EAAoBhlB,KAAKkkB,oBAAoB/mC,IAAIiiB,EAAM7S,OAAOtB,MACpE,GAAI+5B,EAAmB,CACrB5lB,EAAMkD,iBACN,MAAM3G,EAAOqE,KAAKmkB,cAAgBvkC,OAC5BmE,EAASihC,EAAkB3gC,UAAY2b,KAAK4E,SAASvgB,UAC3D,GAAIsX,EAAKspB,SAKP,YAJAtpB,EAAKspB,SAAS,CACZtjC,IAAKoC,EACLmhC,SAAU,WAMdvpB,EAAKlQ,UAAY1H,CACnB,KAEJ,CACA,eAAA8gC,GACE,MAAMpjC,EAAU,CACdka,KAAMqE,KAAKmkB,aACXL,UAAW9jB,KAAK6E,QAAQif,UACxBF,WAAY5jB,KAAK6E,QAAQ+e,YAE3B,OAAO,IAAIuB,sBAAqBhkB,GAAWnB,KAAKolB,kBAAkBjkB,IAAU1f,EAC9E,CAGA,iBAAA2jC,CAAkBjkB,GAChB,MAAMkkB,EAAgB/H,GAAStd,KAAKikB,aAAa9mC,IAAI,IAAImgC,EAAM/wB,OAAO4N,MAChEob,EAAW+H,IACftd,KAAKskB,oBAAoBC,gBAAkBjH,EAAM/wB,OAAOlI,UACxD2b,KAAKslB,SAASD,EAAc/H,GAAO,EAE/BkH,GAAmBxkB,KAAKmkB,cAAgB9+B,SAASC,iBAAiBmG,UAClE85B,EAAkBf,GAAmBxkB,KAAKskB,oBAAoBE,gBACpExkB,KAAKskB,oBAAoBE,gBAAkBA,EAC3C,IAAK,MAAMlH,KAASnc,EAAS,CAC3B,IAAKmc,EAAMkI,eAAgB,CACzBxlB,KAAKokB,cAAgB,KACrBpkB,KAAKylB,kBAAkBJ,EAAc/H,IACrC,QACF,CACA,MAAMoI,EAA2BpI,EAAM/wB,OAAOlI,WAAa2b,KAAKskB,oBAAoBC,gBAEpF,GAAIgB,GAAmBG,GAGrB,GAFAnQ,EAAS+H,IAEJkH,EACH,YAMCe,GAAoBG,GACvBnQ,EAAS+H,EAEb,CACF,CACA,gCAAAoH,GACE1kB,KAAKikB,aAAe,IAAI/yB,IACxB8O,KAAKkkB,oBAAsB,IAAIhzB,IAC/B,MAAMy0B,EAAc/f,GAAezT,KAAKqxB,GAAuBxjB,KAAK6E,QAAQtY,QAC5E,IAAK,MAAMq5B,KAAUD,EAAa,CAEhC,IAAKC,EAAO36B,MAAQiQ,GAAW0qB,GAC7B,SAEF,MAAMZ,EAAoBpf,GAAeC,QAAQggB,UAAUD,EAAO36B,MAAO+U,KAAK4E,UAG1EjK,GAAUqqB,KACZhlB,KAAKikB,aAAalyB,IAAI8zB,UAAUD,EAAO36B,MAAO26B,GAC9C5lB,KAAKkkB,oBAAoBnyB,IAAI6zB,EAAO36B,KAAM+5B,GAE9C,CACF,CACA,QAAAM,CAAS/4B,GACHyT,KAAKokB,gBAAkB73B,IAG3ByT,KAAKylB,kBAAkBzlB,KAAK6E,QAAQtY,QACpCyT,KAAKokB,cAAgB73B,EACrBA,EAAO8O,UAAU5E,IAAI8sB,IACrBvjB,KAAK8lB,iBAAiBv5B,GACtBgU,GAAaqB,QAAQ5B,KAAK4E,SAAUwe,GAAgB,CAClDtjB,cAAevT,IAEnB,CACA,gBAAAu5B,CAAiBv5B,GAEf,GAAIA,EAAO8O,UAAU7W,SA9LQ,iBA+L3BohB,GAAeC,QArLc,mBAqLsBtZ,EAAOyO,QAtLtC,cAsLkEK,UAAU5E,IAAI8sB,SAGtG,IAAK,MAAMwC,KAAangB,GAAeI,QAAQzZ,EA9LnB,qBAiM1B,IAAK,MAAMxJ,KAAQ6iB,GAAeM,KAAK6f,EAAWrC,IAChD3gC,EAAKsY,UAAU5E,IAAI8sB,GAGzB,CACA,iBAAAkC,CAAkBhhC,GAChBA,EAAO4W,UAAU1B,OAAO4pB,IACxB,MAAMyC,EAAcpgB,GAAezT,KAAK,GAAGqxB,MAAyBD,KAAuB9+B,GAC3F,IAAK,MAAM9E,KAAQqmC,EACjBrmC,EAAK0b,UAAU1B,OAAO4pB,GAE1B,CAGA,sBAAO9mB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO25B,GAAU1e,oBAAoBtF,KAAM8D,GACjD,GAAsB,iBAAXA,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOFvD,GAAac,GAAGzhB,OAAQ0jC,IAAuB,KAC7C,IAAK,MAAM2C,KAAOrgB,GAAezT,KApOT,0BAqOtB6xB,GAAU1e,oBAAoB2gB,EAChC,IAOF9pB,GAAmB6nB,IAcnB,MAEMkC,GAAc,UACdC,GAAe,OAAOD,KACtBE,GAAiB,SAASF,KAC1BG,GAAe,OAAOH,KACtBI,GAAgB,QAAQJ,KACxBK,GAAuB,QAAQL,KAC/BM,GAAgB,UAAUN,KAC1BO,GAAsB,OAAOP,KAC7BQ,GAAiB,YACjBC,GAAkB,aAClBC,GAAe,UACfC,GAAiB,YACjBC,GAAW,OACXC,GAAU,MACVC,GAAoB,SACpBC,GAAoB,OACpBC,GAAoB,OAEpBC,GAA2B,mBAE3BC,GAA+B,QAAQD,MAIvCE,GAAuB,2EACvBC,GAAsB,YAFOF,uBAAiDA,mBAA6CA,OAE/EC,KAC5CE,GAA8B,IAAIP,8BAA6CA,+BAA8CA,4BAMnI,MAAMQ,WAAY9iB,GAChB,WAAAP,CAAY5kB,GACVolB,MAAMplB,GACNygB,KAAKiS,QAAUjS,KAAK4E,SAAS5J,QAdN,uCAelBgF,KAAKiS,UAOVjS,KAAKynB,sBAAsBznB,KAAKiS,QAASjS,KAAK0nB,gBAC9CnnB,GAAac,GAAGrB,KAAK4E,SAAU4hB,IAAepnB,GAASY,KAAK0M,SAAStN,KACvE,CAGA,eAAW7C,GACT,MAnDW,KAoDb,CAGA,IAAAmT,GAEE,MAAMiY,EAAY3nB,KAAK4E,SACvB,GAAI5E,KAAK4nB,cAAcD,GACrB,OAIF,MAAME,EAAS7nB,KAAK8nB,iBACdC,EAAYF,EAAStnB,GAAaqB,QAAQimB,EAAQ1B,GAAc,CACpErmB,cAAe6nB,IACZ,KACapnB,GAAaqB,QAAQ+lB,EAAWtB,GAAc,CAC9DvmB,cAAe+nB,IAEH7lB,kBAAoB+lB,GAAaA,EAAU/lB,mBAGzDhC,KAAKgoB,YAAYH,EAAQF,GACzB3nB,KAAKioB,UAAUN,EAAWE,GAC5B,CAGA,SAAAI,CAAU1oC,EAAS2oC,GACZ3oC,IAGLA,EAAQ8b,UAAU5E,IAAIuwB,IACtBhnB,KAAKioB,UAAUriB,GAAec,uBAAuBnnB,IAcrDygB,KAAKmF,gBAZY,KACsB,QAAjC5lB,EAAQic,aAAa,SAIzBjc,EAAQ4B,gBAAgB,YACxB5B,EAAQ6B,aAAa,iBAAiB,GACtC4e,KAAKmoB,gBAAgB5oC,GAAS,GAC9BghB,GAAaqB,QAAQriB,EAAS+mC,GAAe,CAC3CxmB,cAAeooB,KAPf3oC,EAAQ8b,UAAU5E,IAAIywB,GAQtB,GAE0B3nC,EAASA,EAAQ8b,UAAU7W,SAASyiC,KACpE,CACA,WAAAe,CAAYzoC,EAAS2oC,GACd3oC,IAGLA,EAAQ8b,UAAU1B,OAAOqtB,IACzBznC,EAAQm7B,OACR1a,KAAKgoB,YAAYpiB,GAAec,uBAAuBnnB,IAcvDygB,KAAKmF,gBAZY,KACsB,QAAjC5lB,EAAQic,aAAa,SAIzBjc,EAAQ6B,aAAa,iBAAiB,GACtC7B,EAAQ6B,aAAa,WAAY,MACjC4e,KAAKmoB,gBAAgB5oC,GAAS,GAC9BghB,GAAaqB,QAAQriB,EAAS6mC,GAAgB,CAC5CtmB,cAAeooB,KAPf3oC,EAAQ8b,UAAU1B,OAAOutB,GAQzB,GAE0B3nC,EAASA,EAAQ8b,UAAU7W,SAASyiC,KACpE,CACA,QAAAva,CAAStN,GACP,IAAK,CAACsnB,GAAgBC,GAAiBC,GAAcC,GAAgBC,GAAUC,IAAS3lB,SAAShC,EAAMtiB,KACrG,OAEFsiB,EAAMuU,kBACNvU,EAAMkD,iBACN,MAAMwD,EAAW9F,KAAK0nB,eAAevhC,QAAO5G,IAAY2b,GAAW3b,KACnE,IAAI6oC,EACJ,GAAI,CAACtB,GAAUC,IAAS3lB,SAAShC,EAAMtiB,KACrCsrC,EAAoBtiB,EAAS1G,EAAMtiB,MAAQgqC,GAAW,EAAIhhB,EAASpV,OAAS,OACvE,CACL,MAAM2c,EAAS,CAACsZ,GAAiBE,IAAgBzlB,SAAShC,EAAMtiB,KAChEsrC,EAAoBtqB,GAAqBgI,EAAU1G,EAAM7S,OAAQ8gB,GAAQ,EAC3E,CACI+a,IACFA,EAAkB9V,MAAM,CACtB+V,eAAe,IAEjBb,GAAIliB,oBAAoB8iB,GAAmB1Y,OAE/C,CACA,YAAAgY,GAEE,OAAO9hB,GAAezT,KAAKm1B,GAAqBtnB,KAAKiS,QACvD,CACA,cAAA6V,GACE,OAAO9nB,KAAK0nB,eAAev1B,MAAKzN,GAASsb,KAAK4nB,cAAcljC,MAAW,IACzE,CACA,qBAAA+iC,CAAsBhjC,EAAQqhB,GAC5B9F,KAAKsoB,yBAAyB7jC,EAAQ,OAAQ,WAC9C,IAAK,MAAMC,KAASohB,EAClB9F,KAAKuoB,6BAA6B7jC,EAEtC,CACA,4BAAA6jC,CAA6B7jC,GAC3BA,EAAQsb,KAAKwoB,iBAAiB9jC,GAC9B,MAAM+jC,EAAWzoB,KAAK4nB,cAAcljC,GAC9BgkC,EAAY1oB,KAAK2oB,iBAAiBjkC,GACxCA,EAAMtD,aAAa,gBAAiBqnC,GAChCC,IAAchkC,GAChBsb,KAAKsoB,yBAAyBI,EAAW,OAAQ,gBAE9CD,GACH/jC,EAAMtD,aAAa,WAAY,MAEjC4e,KAAKsoB,yBAAyB5jC,EAAO,OAAQ,OAG7Csb,KAAK4oB,mCAAmClkC,EAC1C,CACA,kCAAAkkC,CAAmClkC,GACjC,MAAM6H,EAASqZ,GAAec,uBAAuBhiB,GAChD6H,IAGLyT,KAAKsoB,yBAAyB/7B,EAAQ,OAAQ,YAC1C7H,EAAMyV,IACR6F,KAAKsoB,yBAAyB/7B,EAAQ,kBAAmB,GAAG7H,EAAMyV,MAEtE,CACA,eAAAguB,CAAgB5oC,EAASspC,GACvB,MAAMH,EAAY1oB,KAAK2oB,iBAAiBppC,GACxC,IAAKmpC,EAAUrtB,UAAU7W,SApKN,YAqKjB,OAEF,MAAMkjB,EAAS,CAAC3N,EAAUia,KACxB,MAAMz0B,EAAUqmB,GAAeC,QAAQ9L,EAAU2uB,GAC7CnpC,GACFA,EAAQ8b,UAAUqM,OAAOsM,EAAW6U,EACtC,EAEFnhB,EAAOyf,GAA0BH,IACjCtf,EA5K2B,iBA4KIwf,IAC/BwB,EAAUtnC,aAAa,gBAAiBynC,EAC1C,CACA,wBAAAP,CAAyB/oC,EAASwC,EAAWpE,GACtC4B,EAAQgc,aAAaxZ,IACxBxC,EAAQ6B,aAAaW,EAAWpE,EAEpC,CACA,aAAAiqC,CAAczY,GACZ,OAAOA,EAAK9T,UAAU7W,SAASwiC,GACjC,CAGA,gBAAAwB,CAAiBrZ,GACf,OAAOA,EAAKpJ,QAAQuhB,IAAuBnY,EAAOvJ,GAAeC,QAAQyhB,GAAqBnY,EAChG,CAGA,gBAAAwZ,CAAiBxZ,GACf,OAAOA,EAAKnU,QA5LO,gCA4LoBmU,CACzC,CAGA,sBAAO1S,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOm9B,GAAIliB,oBAAoBtF,MACrC,GAAsB,iBAAX8D,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOFvD,GAAac,GAAGhc,SAAUkhC,GAAsBc,IAAsB,SAAUjoB,GAC1E,CAAC,IAAK,QAAQgC,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAEJpH,GAAW8E,OAGfwnB,GAAIliB,oBAAoBtF,MAAM0P,MAChC,IAKAnP,GAAac,GAAGzhB,OAAQ6mC,IAAqB,KAC3C,IAAK,MAAMlnC,KAAWqmB,GAAezT,KAAKo1B,IACxCC,GAAIliB,oBAAoB/lB,EAC1B,IAMF4c,GAAmBqrB,IAcnB,MAEMxiB,GAAY,YACZ8jB,GAAkB,YAAY9jB,KAC9B+jB,GAAiB,WAAW/jB,KAC5BgkB,GAAgB,UAAUhkB,KAC1BikB,GAAiB,WAAWjkB,KAC5BkkB,GAAa,OAAOlkB,KACpBmkB,GAAe,SAASnkB,KACxBokB,GAAa,OAAOpkB,KACpBqkB,GAAc,QAAQrkB,KAEtBskB,GAAkB,OAClBC,GAAkB,OAClBC,GAAqB,UACrB7lB,GAAc,CAClBmc,UAAW,UACX2J,SAAU,UACVxJ,MAAO,UAEHvc,GAAU,CACdoc,WAAW,EACX2J,UAAU,EACVxJ,MAAO,KAOT,MAAMyJ,WAAchlB,GAClB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKsgB,SAAW,KAChBtgB,KAAK2pB,sBAAuB,EAC5B3pB,KAAK4pB,yBAA0B,EAC/B5pB,KAAK4gB,eACP,CAGA,kBAAWld,GACT,OAAOA,EACT,CACA,sBAAWC,GACT,OAAOA,EACT,CACA,eAAWpH,GACT,MA/CS,OAgDX,CAGA,IAAAmT,GACoBnP,GAAaqB,QAAQ5B,KAAK4E,SAAUwkB,IACxCpnB,mBAGdhC,KAAK6pB,gBACD7pB,KAAK6E,QAAQib,WACf9f,KAAK4E,SAASvJ,UAAU5E,IA/CN,QAsDpBuJ,KAAK4E,SAASvJ,UAAU1B,OAAO2vB,IAC/BztB,GAAOmE,KAAK4E,UACZ5E,KAAK4E,SAASvJ,UAAU5E,IAAI8yB,GAAiBC,IAC7CxpB,KAAKmF,gBARY,KACfnF,KAAK4E,SAASvJ,UAAU1B,OAAO6vB,IAC/BjpB,GAAaqB,QAAQ5B,KAAK4E,SAAUykB,IACpCrpB,KAAK8pB,oBAAoB,GAKG9pB,KAAK4E,SAAU5E,KAAK6E,QAAQib,WAC5D,CACA,IAAArQ,GACOzP,KAAK+pB,YAGQxpB,GAAaqB,QAAQ5B,KAAK4E,SAAUskB,IACxClnB,mBAQdhC,KAAK4E,SAASvJ,UAAU5E,IAAI+yB,IAC5BxpB,KAAKmF,gBANY,KACfnF,KAAK4E,SAASvJ,UAAU5E,IAAI6yB,IAC5BtpB,KAAK4E,SAASvJ,UAAU1B,OAAO6vB,GAAoBD,IACnDhpB,GAAaqB,QAAQ5B,KAAK4E,SAAUukB,GAAa,GAGrBnpB,KAAK4E,SAAU5E,KAAK6E,QAAQib,YAC5D,CACA,OAAA/a,GACE/E,KAAK6pB,gBACD7pB,KAAK+pB,WACP/pB,KAAK4E,SAASvJ,UAAU1B,OAAO4vB,IAEjC5kB,MAAMI,SACR,CACA,OAAAglB,GACE,OAAO/pB,KAAK4E,SAASvJ,UAAU7W,SAAS+kC,GAC1C,CAIA,kBAAAO,GACO9pB,KAAK6E,QAAQ4kB,WAGdzpB,KAAK2pB,sBAAwB3pB,KAAK4pB,0BAGtC5pB,KAAKsgB,SAAWziB,YAAW,KACzBmC,KAAKyP,MAAM,GACVzP,KAAK6E,QAAQob,QAClB,CACA,cAAA+J,CAAe5qB,EAAO6qB,GACpB,OAAQ7qB,EAAMqB,MACZ,IAAK,YACL,IAAK,WAEDT,KAAK2pB,qBAAuBM,EAC5B,MAEJ,IAAK,UACL,IAAK,WAEDjqB,KAAK4pB,wBAA0BK,EAIrC,GAAIA,EAEF,YADAjqB,KAAK6pB,gBAGP,MAAMvc,EAAclO,EAAMU,cACtBE,KAAK4E,WAAa0I,GAAetN,KAAK4E,SAASpgB,SAAS8oB,IAG5DtN,KAAK8pB,oBACP,CACA,aAAAlJ,GACErgB,GAAac,GAAGrB,KAAK4E,SAAUkkB,IAAiB1pB,GAASY,KAAKgqB,eAAe5qB,GAAO,KACpFmB,GAAac,GAAGrB,KAAK4E,SAAUmkB,IAAgB3pB,GAASY,KAAKgqB,eAAe5qB,GAAO,KACnFmB,GAAac,GAAGrB,KAAK4E,SAAUokB,IAAe5pB,GAASY,KAAKgqB,eAAe5qB,GAAO,KAClFmB,GAAac,GAAGrB,KAAK4E,SAAUqkB,IAAgB7pB,GAASY,KAAKgqB,eAAe5qB,GAAO,IACrF,CACA,aAAAyqB,GACE9c,aAAa/M,KAAKsgB,UAClBtgB,KAAKsgB,SAAW,IAClB,CAGA,sBAAO7jB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOq/B,GAAMpkB,oBAAoBtF,KAAM8D,GAC7C,GAAsB,iBAAXA,EAAqB,CAC9B,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQ9D,KACf,CACF,GACF,ECr0IK,SAASkqB,GAAc7tB,GACD,WAAvBhX,SAASuX,WAAyBP,IACjChX,SAASyF,iBAAiB,mBAAoBuR,EACrD,CDy0IAuK,GAAqB8iB,IAMrBvtB,GAAmButB,IEpyInBQ,IAzCA,WAC2B,GAAG93B,MAAM5U,KAChC6H,SAAS+a,iBAAiB,+BAETtd,KAAI,SAAUqnC,GAC/B,OAAO,IAAI,GAAkBA,EAAkB,CAC7ClK,MAAO,CAAEvQ,KAAM,IAAKD,KAAM,MAE9B,GACF,IAiCAya,IA5BA,WACY7kC,SAAS68B,eAAe,mBAC9Bp3B,iBAAiB,SAAS,WAC5BzF,SAAS6G,KAAKT,UAAY,EAC1BpG,SAASC,gBAAgBmG,UAAY,CACvC,GACF,IAuBAy+B,IArBA,WACE,IAAIE,EAAM/kC,SAAS68B,eAAe,mBAC9BmI,EAAShlC,SACVilC,uBAAuB,aAAa,GACpChnC,wBACH1D,OAAOkL,iBAAiB,UAAU,WAC5BkV,KAAKuqB,UAAYvqB,KAAKwqB,SAAWxqB,KAAKwqB,QAAUH,EAAOzsC,OACzDwsC,EAAIrpC,MAAM6wB,QAAU,QAEpBwY,EAAIrpC,MAAM6wB,QAAU,OAEtB5R,KAAKuqB,UAAYvqB,KAAKwqB,OACxB,GACF,IAUA5qC,OAAO6qC,UAAY","sources":["webpack://pydata_sphinx_theme/webpack/bootstrap","webpack://pydata_sphinx_theme/webpack/runtime/define property getters","webpack://pydata_sphinx_theme/webpack/runtime/hasOwnProperty shorthand","webpack://pydata_sphinx_theme/webpack/runtime/make namespace object","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/enums.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/applyStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getBasePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/math.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/userAgent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/contains.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/within.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/expandToHashMap.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/arrow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getVariation.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/computeStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/eventListeners.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/rectToClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/detectOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/flip.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/hide.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/offset.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getAltAxis.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/orderModifiers.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/createPopper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/debounce.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergeByName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper-lite.js","webpack://pydata_sphinx_theme/./node_modules/bootstrap/dist/js/bootstrap.esm.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/mixin.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/bootstrap.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref, win) {\n var x = _ref.x,\n y = _ref.y;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }, getWindow(popper)) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n });\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref) {\n var name = _ref.name,\n _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n effect = _ref.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","/*!\n * Bootstrap v5.3.2 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nimport * as Popper from '@popperjs/core';\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map();\nconst Data = {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map());\n }\n const instanceMap = elementMap.get(element);\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n return;\n }\n instanceMap.set(key, instance);\n },\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null;\n }\n return null;\n },\n remove(element, key) {\n if (!elementMap.has(element)) {\n return;\n }\n const instanceMap = elementMap.get(element);\n instanceMap.delete(key);\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element);\n }\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1000000;\nconst MILLISECONDS_MULTIPLIER = 1000;\nconst TRANSITION_END = 'transitionend';\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`);\n }\n return selector;\n};\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`;\n }\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase();\n};\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID);\n } while (document.getElementById(prefix));\n return prefix;\n};\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0;\n }\n\n // Get transition-duration of the element\n let {\n transitionDuration,\n transitionDelay\n } = window.getComputedStyle(element);\n const floatTransitionDuration = Number.parseFloat(transitionDuration);\n const floatTransitionDelay = Number.parseFloat(transitionDelay);\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n};\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END));\n};\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false;\n }\n if (typeof object.jquery !== 'undefined') {\n object = object[0];\n }\n return typeof object.nodeType !== 'undefined';\n};\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object;\n }\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object));\n }\n return null;\n};\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false;\n }\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])');\n if (!closedDetails) {\n return elementIsVisible;\n }\n if (closedDetails !== element) {\n const summary = element.closest('summary');\n if (summary && summary.parentNode !== closedDetails) {\n return false;\n }\n if (summary === null) {\n return false;\n }\n }\n return elementIsVisible;\n};\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n if (element.classList.contains('disabled')) {\n return true;\n }\n if (typeof element.disabled !== 'undefined') {\n return element.disabled;\n }\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n};\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null;\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n if (element instanceof ShadowRoot) {\n return element;\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null;\n }\n return findShadowRoot(element.parentNode);\n};\nconst noop = () => {};\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight; // eslint-disable-line no-unused-expressions\n};\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery;\n }\n return null;\n};\nconst DOMContentLoadedCallbacks = [];\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback();\n }\n });\n }\n DOMContentLoadedCallbacks.push(callback);\n } else {\n callback();\n }\n};\nconst isRTL = () => document.documentElement.dir === 'rtl';\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery();\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME;\n const JQUERY_NO_CONFLICT = $.fn[name];\n $.fn[name] = plugin.jQueryInterface;\n $.fn[name].Constructor = plugin;\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT;\n return plugin.jQueryInterface;\n };\n }\n });\n};\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;\n};\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback);\n return;\n }\n const durationPadding = 5;\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n let called = false;\n const handler = ({\n target\n }) => {\n if (target !== transitionElement) {\n return;\n }\n called = true;\n transitionElement.removeEventListener(TRANSITION_END, handler);\n execute(callback);\n };\n transitionElement.addEventListener(TRANSITION_END, handler);\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement);\n }\n }, emulatedDuration);\n};\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length;\n let index = list.indexOf(activeElement);\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];\n }\n index += shouldGetNext ? 1 : -1;\n if (isCycleAllowed) {\n index = (index + listLength) % listLength;\n }\n return list[Math.max(0, Math.min(index, listLength - 1))];\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\nconst stripNameRegex = /\\..*/;\nconst stripUidRegex = /::\\d+$/;\nconst eventRegistry = {}; // Events storage\nlet uidEvent = 1;\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n};\nconst nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n}\nfunction getElementEvents(element) {\n const uid = makeEventUid(element);\n element.uidEvent = uid;\n eventRegistry[uid] = eventRegistry[uid] || {};\n return eventRegistry[uid];\n}\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, {\n delegateTarget: element\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn);\n }\n return fn.apply(element, [event]);\n };\n}\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector);\n for (let {\n target\n } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue;\n }\n hydrateObj(event, {\n delegateTarget: target\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn);\n }\n return fn.apply(target, [event]);\n }\n }\n };\n}\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);\n}\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string';\n // TODO: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : handler || delegationFunction;\n let typeEvent = getTypeEvent(originalTypeEvent);\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent;\n }\n return [isDelegated, callable, typeEvent];\n}\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n return fn.call(this, event);\n }\n };\n };\n callable = wrapFunction(callable);\n }\n const events = getElementEvents(element);\n const handlers = events[typeEvent] || (events[typeEvent] = {});\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff;\n return;\n }\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));\n const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);\n fn.delegationSelector = isDelegated ? handler : null;\n fn.callable = callable;\n fn.oneOff = oneOff;\n fn.uidEvent = uid;\n handlers[uid] = fn;\n element.addEventListener(typeEvent, fn, isDelegated);\n}\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector);\n if (!fn) {\n return;\n }\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n delete events[typeEvent][fn.uidEvent];\n}\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {};\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n}\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '');\n return customEvents[event] || event;\n}\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false);\n },\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true);\n },\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n const inNamespace = typeEvent !== originalTypeEvent;\n const events = getElementEvents(element);\n const storeElementEvent = events[typeEvent] || {};\n const isNamespace = originalTypeEvent.startsWith('.');\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return;\n }\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);\n return;\n }\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n }\n }\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '');\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n },\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null;\n }\n const $ = getjQuery();\n const typeEvent = getTypeEvent(event);\n const inNamespace = event !== typeEvent;\n let jQueryEvent = null;\n let bubbles = true;\n let nativeDispatch = true;\n let defaultPrevented = false;\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args);\n $(element).trigger(jQueryEvent);\n bubbles = !jQueryEvent.isPropagationStopped();\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n defaultPrevented = jQueryEvent.isDefaultPrevented();\n }\n const evt = hydrateObj(new Event(event, {\n bubbles,\n cancelable: true\n }), args);\n if (defaultPrevented) {\n evt.preventDefault();\n }\n if (nativeDispatch) {\n element.dispatchEvent(evt);\n }\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault();\n }\n return evt;\n }\n};\nfunction hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n try {\n obj[key] = value;\n } catch (_unused) {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value;\n }\n });\n }\n }\n return obj;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n if (value === Number(value).toString()) {\n return Number(value);\n }\n if (value === '' || value === 'null') {\n return null;\n }\n if (typeof value !== 'string') {\n return value;\n }\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (_unused) {\n return value;\n }\n}\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n}\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n },\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n },\n getDataAttributes(element) {\n if (!element) {\n return {};\n }\n const attributes = {};\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '');\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n attributes[pureKey] = normalizeData(element.dataset[key]);\n }\n return attributes;\n },\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {};\n }\n static get DefaultType() {\n return {};\n }\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!');\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n return config;\n }\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n };\n }\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property];\n const valueType = isElement(value) ? 'element' : toType(value);\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n }\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.2';\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super();\n element = getElement(element);\n if (!element) {\n return;\n }\n this._element = element;\n this._config = this._getConfig(config);\n Data.set(this._element, this.constructor.DATA_KEY, this);\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY);\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null;\n }\n }\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated);\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY);\n }\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n }\n static get VERSION() {\n return VERSION;\n }\n static get DATA_KEY() {\n return `bs.${this.NAME}`;\n }\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`;\n }\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target');\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href');\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {\n return null;\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`;\n }\n selector = hrefAttribute && hrefAttribute !== '#' ? parseSelector(hrefAttribute.trim()) : null;\n }\n return selector;\n};\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n },\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector);\n },\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector));\n },\n parents(element, selector) {\n const parents = [];\n let ancestor = element.parentNode.closest(selector);\n while (ancestor) {\n parents.push(ancestor);\n ancestor = ancestor.parentNode.closest(selector);\n }\n return parents;\n },\n prev(element, selector) {\n let previous = element.previousElementSibling;\n while (previous) {\n if (previous.matches(selector)) {\n return [previous];\n }\n previous = previous.previousElementSibling;\n }\n return [];\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling;\n while (next) {\n if (next.matches(selector)) {\n return [next];\n }\n next = next.nextElementSibling;\n }\n return [];\n },\n focusableChildren(element) {\n const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',');\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n },\n getSelectorFromElement(element) {\n const selector = getSelector(element);\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null;\n }\n return null;\n },\n getElementFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.findOne(selector) : null;\n },\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.find(selector) : [];\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n const name = component.NAME;\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);\n const instance = component.getOrCreateInstance(target);\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]();\n });\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$f = 'alert';\nconst DATA_KEY$a = 'bs.alert';\nconst EVENT_KEY$b = `.${DATA_KEY$a}`;\nconst EVENT_CLOSE = `close${EVENT_KEY$b}`;\nconst EVENT_CLOSED = `closed${EVENT_KEY$b}`;\nconst CLASS_NAME_FADE$5 = 'fade';\nconst CLASS_NAME_SHOW$8 = 'show';\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$f;\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n if (closeEvent.defaultPrevented) {\n return;\n }\n this._element.classList.remove(CLASS_NAME_SHOW$8);\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n }\n\n // Private\n _destroyElement() {\n this._element.remove();\n EventHandler.trigger(this._element, EVENT_CLOSED);\n this.dispose();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close');\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$e = 'button';\nconst DATA_KEY$9 = 'bs.button';\nconst EVENT_KEY$a = `.${DATA_KEY$9}`;\nconst DATA_API_KEY$6 = '.data-api';\nconst CLASS_NAME_ACTIVE$3 = 'active';\nconst SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\nconst EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$e;\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this);\n if (config === 'toggle') {\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n event.preventDefault();\n const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n const data = Button.getOrCreateInstance(button);\n data.toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$d = 'swipe';\nconst EVENT_KEY$9 = '.bs.swipe';\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;\nconst POINTER_TYPE_TOUCH = 'touch';\nconst POINTER_TYPE_PEN = 'pen';\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event';\nconst SWIPE_THRESHOLD = 40;\nconst Default$c = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n};\nconst DefaultType$c = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n};\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super();\n this._element = element;\n if (!element || !Swipe.isSupported()) {\n return;\n }\n this._config = this._getConfig(config);\n this._deltaX = 0;\n this._supportPointerEvents = Boolean(window.PointerEvent);\n this._initEvents();\n }\n\n // Getters\n static get Default() {\n return Default$c;\n }\n static get DefaultType() {\n return DefaultType$c;\n }\n static get NAME() {\n return NAME$d;\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY$9);\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX;\n return;\n }\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX;\n }\n }\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX;\n }\n this._handleSwipe();\n execute(this._config.endCallback);\n }\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;\n }\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX);\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return;\n }\n const direction = absDeltaX / this._deltaX;\n this._deltaX = 0;\n if (!direction) {\n return;\n }\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);\n }\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));\n this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));\n }\n }\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$c = 'carousel';\nconst DATA_KEY$8 = 'bs.carousel';\nconst EVENT_KEY$8 = `.${DATA_KEY$8}`;\nconst DATA_API_KEY$5 = '.data-api';\nconst ARROW_LEFT_KEY$1 = 'ArrowLeft';\nconst ARROW_RIGHT_KEY$1 = 'ArrowRight';\nconst TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next';\nconst ORDER_PREV = 'prev';\nconst DIRECTION_LEFT = 'left';\nconst DIRECTION_RIGHT = 'right';\nconst EVENT_SLIDE = `slide${EVENT_KEY$8}`;\nconst EVENT_SLID = `slid${EVENT_KEY$8}`;\nconst EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;\nconst EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;\nconst EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;\nconst EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst CLASS_NAME_CAROUSEL = 'carousel';\nconst CLASS_NAME_ACTIVE$2 = 'active';\nconst CLASS_NAME_SLIDE = 'slide';\nconst CLASS_NAME_END = 'carousel-item-end';\nconst CLASS_NAME_START = 'carousel-item-start';\nconst CLASS_NAME_NEXT = 'carousel-item-next';\nconst CLASS_NAME_PREV = 'carousel-item-prev';\nconst SELECTOR_ACTIVE = '.active';\nconst SELECTOR_ITEM = '.carousel-item';\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;\nconst SELECTOR_ITEM_IMG = '.carousel-item img';\nconst SELECTOR_INDICATORS = '.carousel-indicators';\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT\n};\nconst Default$b = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n};\nconst DefaultType$b = {\n interval: '(number|boolean)',\n // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._interval = null;\n this._activeElement = null;\n this._isSliding = false;\n this.touchTimeout = null;\n this._swipeHelper = null;\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n this._addEventListeners();\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$b;\n }\n static get DefaultType() {\n return DefaultType$b;\n }\n static get NAME() {\n return NAME$c;\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT);\n }\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next();\n }\n }\n prev() {\n this._slide(ORDER_PREV);\n }\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element);\n }\n this._clearInterval();\n }\n cycle() {\n this._clearInterval();\n this._updateInterval();\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);\n }\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle());\n return;\n }\n this.cycle();\n }\n to(index) {\n const items = this._getItems();\n if (index > items.length - 1 || index < 0) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n return;\n }\n const activeIndex = this._getItemIndex(this._getActive());\n if (activeIndex === index) {\n return;\n }\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n this._slide(order, items[index]);\n }\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose();\n }\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval;\n return config;\n }\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));\n }\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());\n EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());\n }\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners();\n }\n }\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());\n }\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return;\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause();\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout);\n }\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n };\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n };\n this._swipeHelper = new Swipe(this._element, swipeConfig);\n }\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return;\n }\n const direction = KEY_TO_DIRECTION[event.key];\n if (direction) {\n event.preventDefault();\n this._slide(this._directionToOrder(direction));\n }\n }\n _getItemIndex(element) {\n return this._getItems().indexOf(element);\n }\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return;\n }\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n activeIndicator.removeAttribute('aria-current');\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement);\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);\n newActiveIndicator.setAttribute('aria-current', 'true');\n }\n }\n _updateInterval() {\n const element = this._activeElement || this._getActive();\n if (!element) {\n return;\n }\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n this._config.interval = elementInterval || this._config.defaultInterval;\n }\n _slide(order, element = null) {\n if (this._isSliding) {\n return;\n }\n const activeElement = this._getActive();\n const isNext = order === ORDER_NEXT;\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);\n if (nextElement === activeElement) {\n return;\n }\n const nextElementIndex = this._getItemIndex(nextElement);\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n });\n };\n const slideEvent = triggerEvent(EVENT_SLIDE);\n if (slideEvent.defaultPrevented) {\n return;\n }\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // TODO: change tests that use empty divs to avoid this check\n return;\n }\n const isCycling = Boolean(this._interval);\n this.pause();\n this._isSliding = true;\n this._setActiveIndicatorElement(nextElementIndex);\n this._activeElement = nextElement;\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n nextElement.classList.add(orderClassName);\n reflow(nextElement);\n activeElement.classList.add(directionalClassName);\n nextElement.classList.add(directionalClassName);\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName);\n nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n this._isSliding = false;\n triggerEvent(EVENT_SLID);\n };\n this._queueCallback(completeCallBack, activeElement, this._isAnimated());\n if (isCycling) {\n this.cycle();\n }\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE);\n }\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n }\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element);\n }\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval);\n this._interval = null;\n }\n }\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n }\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n }\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config);\n if (typeof config === 'number') {\n data.to(config);\n return;\n }\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return;\n }\n event.preventDefault();\n const carousel = Carousel.getOrCreateInstance(target);\n const slideIndex = this.getAttribute('data-bs-slide-to');\n if (slideIndex) {\n carousel.to(slideIndex);\n carousel._maybeEnableCycle();\n return;\n }\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next();\n carousel._maybeEnableCycle();\n return;\n }\n carousel.prev();\n carousel._maybeEnableCycle();\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel);\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$b = 'collapse';\nconst DATA_KEY$7 = 'bs.collapse';\nconst EVENT_KEY$7 = `.${DATA_KEY$7}`;\nconst DATA_API_KEY$4 = '.data-api';\nconst EVENT_SHOW$6 = `show${EVENT_KEY$7}`;\nconst EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;\nconst EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;\nconst EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;\nconst EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;\nconst CLASS_NAME_SHOW$7 = 'show';\nconst CLASS_NAME_COLLAPSE = 'collapse';\nconst CLASS_NAME_COLLAPSING = 'collapsing';\nconst CLASS_NAME_COLLAPSED = 'collapsed';\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\nconst WIDTH = 'width';\nconst HEIGHT = 'height';\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\nconst SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\nconst Default$a = {\n parent: null,\n toggle: true\n};\nconst DefaultType$a = {\n parent: '(null|element)',\n toggle: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isTransitioning = false;\n this._triggerArray = [];\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem);\n const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem);\n }\n }\n this._initializeChildren();\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n }\n if (this._config.toggle) {\n this.toggle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$a;\n }\n static get DefaultType() {\n return DefaultType$a;\n }\n static get NAME() {\n return NAME$b;\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide();\n } else {\n this.show();\n }\n }\n show() {\n if (this._isTransitioning || this._isShown()) {\n return;\n }\n let activeChildren = [];\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {\n toggle: false\n }));\n }\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n for (const activeInstance of activeChildren) {\n activeInstance.hide();\n }\n const dimension = this._getDimension();\n this._element.classList.remove(CLASS_NAME_COLLAPSE);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.style[dimension] = 0;\n this._addAriaAndCollapsedClass(this._triggerArray, true);\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n this._element.style[dimension] = '';\n EventHandler.trigger(this._element, EVENT_SHOWN$6);\n };\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n const scrollSize = `scroll${capitalizedDimension}`;\n this._queueCallback(complete, this._element, true);\n this._element.style[dimension] = `${this._element[scrollSize]}px`;\n }\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n const dimension = this._getDimension();\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger);\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false);\n }\n }\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE);\n EventHandler.trigger(this._element, EVENT_HIDDEN$6);\n };\n this._element.style[dimension] = '';\n this._queueCallback(complete, this._element, true);\n }\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW$7);\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle); // Coerce string values\n config.parent = getElement(config.parent);\n return config;\n }\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n }\n _initializeChildren() {\n if (!this._config.parent) {\n return;\n }\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element);\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected));\n }\n }\n }\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));\n }\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return;\n }\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);\n element.setAttribute('aria-expanded', isOpen);\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {};\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false;\n }\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config);\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n event.preventDefault();\n }\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, {\n toggle: false\n }).toggle();\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$a = 'dropdown';\nconst DATA_KEY$6 = 'bs.dropdown';\nconst EVENT_KEY$6 = `.${DATA_KEY$6}`;\nconst DATA_API_KEY$3 = '.data-api';\nconst ESCAPE_KEY$2 = 'Escape';\nconst TAB_KEY$1 = 'Tab';\nconst ARROW_UP_KEY$1 = 'ArrowUp';\nconst ARROW_DOWN_KEY$1 = 'ArrowDown';\nconst RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;\nconst EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;\nconst EVENT_SHOW$5 = `show${EVENT_KEY$6}`;\nconst EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;\nconst EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst CLASS_NAME_SHOW$6 = 'show';\nconst CLASS_NAME_DROPUP = 'dropup';\nconst CLASS_NAME_DROPEND = 'dropend';\nconst CLASS_NAME_DROPSTART = 'dropstart';\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center';\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';\nconst SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)';\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;\nconst SELECTOR_MENU = '.dropdown-menu';\nconst SELECTOR_NAVBAR = '.navbar';\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav';\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\nconst PLACEMENT_TOPCENTER = 'top';\nconst PLACEMENT_BOTTOMCENTER = 'bottom';\nconst Default$9 = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n};\nconst DefaultType$9 = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n};\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._popper = null;\n this._parent = this._element.parentNode; // dropdown wrapper\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);\n this._inNavbar = this._detectNavbar();\n }\n\n // Getters\n static get Default() {\n return Default$9;\n }\n static get DefaultType() {\n return DefaultType$9;\n }\n static get NAME() {\n return NAME$a;\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show();\n }\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);\n if (showEvent.defaultPrevented) {\n return;\n }\n this._createPopper();\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n this._element.focus();\n this._element.setAttribute('aria-expanded', true);\n this._menu.classList.add(CLASS_NAME_SHOW$6);\n this._element.classList.add(CLASS_NAME_SHOW$6);\n EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);\n }\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n this._completeHide(relatedTarget);\n }\n dispose() {\n if (this._popper) {\n this._popper.destroy();\n }\n super.dispose();\n }\n update() {\n this._inNavbar = this._detectNavbar();\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n if (this._popper) {\n this._popper.destroy();\n }\n this._menu.classList.remove(CLASS_NAME_SHOW$6);\n this._element.classList.remove(CLASS_NAME_SHOW$6);\n this._element.setAttribute('aria-expanded', 'false');\n Manipulator.removeDataAttribute(this._menu, 'popper');\n EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);\n }\n _getConfig(config) {\n config = super._getConfig(config);\n if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME$a.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n }\n return config;\n }\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n }\n let referenceElement = this._element;\n if (this._config.reference === 'parent') {\n referenceElement = this._parent;\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference);\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference;\n }\n const popperConfig = this._getPopperConfig();\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);\n }\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW$6);\n }\n _getPlacement() {\n const parentDropdown = this._parent;\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER;\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n }\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n }\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null;\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n };\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }];\n }\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _selectMenuItem({\n key,\n target\n }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));\n if (!items.length) {\n return;\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {\n return;\n }\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle);\n if (!context || context._config.autoClose === false) {\n continue;\n }\n const composedPath = event.composedPath();\n const isMenuTarget = composedPath.includes(context._menu);\n if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n continue;\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue;\n }\n const relatedTarget = {\n relatedTarget: context._element\n };\n if (event.type === 'click') {\n relatedTarget.clickEvent = event;\n }\n context._completeHide(relatedTarget);\n }\n }\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName);\n const isEscapeEvent = event.key === ESCAPE_KEY$2;\n const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return;\n }\n if (isInput && !isEscapeEvent) {\n return;\n }\n event.preventDefault();\n\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);\n const instance = Dropdown.getOrCreateInstance(getToggleButton);\n if (isUpOrDownEvent) {\n event.stopPropagation();\n instance.show();\n instance._selectMenuItem(event);\n return;\n }\n if (instance._isShown()) {\n // else is escape and we check if it is shown\n event.stopPropagation();\n instance.hide();\n getToggleButton.focus();\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n event.preventDefault();\n Dropdown.getOrCreateInstance(this).toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$9 = 'backdrop';\nconst CLASS_NAME_FADE$4 = 'fade';\nconst CLASS_NAME_SHOW$5 = 'show';\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;\nconst Default$8 = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true,\n // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n};\n\nconst DefaultType$8 = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n};\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isAppended = false;\n this._element = null;\n }\n\n // Getters\n static get Default() {\n return Default$8;\n }\n static get DefaultType() {\n return DefaultType$8;\n }\n static get NAME() {\n return NAME$9;\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._append();\n const element = this._getElement();\n if (this._config.isAnimated) {\n reflow(element);\n }\n element.classList.add(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n execute(callback);\n });\n }\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n this.dispose();\n execute(callback);\n });\n }\n dispose() {\n if (!this._isAppended) {\n return;\n }\n EventHandler.off(this._element, EVENT_MOUSEDOWN);\n this._element.remove();\n this._isAppended = false;\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div');\n backdrop.className = this._config.className;\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE$4);\n }\n this._element = backdrop;\n }\n return this._element;\n }\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement);\n return config;\n }\n _append() {\n if (this._isAppended) {\n return;\n }\n const element = this._getElement();\n this._config.rootElement.append(element);\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback);\n });\n this._isAppended = true;\n }\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$8 = 'focustrap';\nconst DATA_KEY$5 = 'bs.focustrap';\nconst EVENT_KEY$5 = `.${DATA_KEY$5}`;\nconst EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;\nconst TAB_KEY = 'Tab';\nconst TAB_NAV_FORWARD = 'forward';\nconst TAB_NAV_BACKWARD = 'backward';\nconst Default$7 = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n};\n\nconst DefaultType$7 = {\n autofocus: 'boolean',\n trapElement: 'element'\n};\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isActive = false;\n this._lastTabNavDirection = null;\n }\n\n // Getters\n static get Default() {\n return Default$7;\n }\n static get DefaultType() {\n return DefaultType$7;\n }\n static get NAME() {\n return NAME$8;\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return;\n }\n if (this._config.autofocus) {\n this._config.trapElement.focus();\n }\n EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n this._isActive = true;\n }\n deactivate() {\n if (!this._isActive) {\n return;\n }\n this._isActive = false;\n EventHandler.off(document, EVENT_KEY$5);\n }\n\n // Private\n _handleFocusin(event) {\n const {\n trapElement\n } = this._config;\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return;\n }\n const elements = SelectorEngine.focusableChildren(trapElement);\n if (elements.length === 0) {\n trapElement.focus();\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus();\n } else {\n elements[0].focus();\n }\n }\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return;\n }\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\nconst SELECTOR_STICKY_CONTENT = '.sticky-top';\nconst PROPERTY_PADDING = 'padding-right';\nconst PROPERTY_MARGIN = 'margin-right';\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body;\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth;\n return Math.abs(window.innerWidth - documentWidth);\n }\n hide() {\n const width = this.getWidth();\n this._disableOverFlow();\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);\n }\n reset() {\n this._resetElementAttributes(this._element, 'overflow');\n this._resetElementAttributes(this._element, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);\n }\n isOverflowing() {\n return this.getWidth() > 0;\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow');\n this._element.style.overflow = 'hidden';\n }\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth();\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return;\n }\n this._saveInitialAttribute(element, styleProperty);\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty);\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue);\n }\n }\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty);\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty);\n return;\n }\n Manipulator.removeDataAttribute(element, styleProperty);\n element.style.setProperty(styleProperty, value);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector);\n return;\n }\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel);\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$7 = 'modal';\nconst DATA_KEY$4 = 'bs.modal';\nconst EVENT_KEY$4 = `.${DATA_KEY$4}`;\nconst DATA_API_KEY$2 = '.data-api';\nconst ESCAPE_KEY$1 = 'Escape';\nconst EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;\nconst EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;\nconst EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;\nconst EVENT_SHOW$4 = `show${EVENT_KEY$4}`;\nconst EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;\nconst EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;\nconst EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;\nconst EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;\nconst CLASS_NAME_OPEN = 'modal-open';\nconst CLASS_NAME_FADE$3 = 'fade';\nconst CLASS_NAME_SHOW$4 = 'show';\nconst CLASS_NAME_STATIC = 'modal-static';\nconst OPEN_SELECTOR$1 = '.modal.show';\nconst SELECTOR_DIALOG = '.modal-dialog';\nconst SELECTOR_MODAL_BODY = '.modal-body';\nconst SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\nconst Default$6 = {\n backdrop: true,\n focus: true,\n keyboard: true\n};\nconst DefaultType$6 = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._isShown = false;\n this._isTransitioning = false;\n this._scrollBar = new ScrollBarHelper();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$6;\n }\n static get DefaultType() {\n return DefaultType$6;\n }\n static get NAME() {\n return NAME$7;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._isTransitioning = true;\n this._scrollBar.hide();\n document.body.classList.add(CLASS_NAME_OPEN);\n this._adjustDialog();\n this._backdrop.show(() => this._showElement(relatedTarget));\n }\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._isShown = false;\n this._isTransitioning = true;\n this._focustrap.deactivate();\n this._element.classList.remove(CLASS_NAME_SHOW$4);\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());\n }\n dispose() {\n EventHandler.off(window, EVENT_KEY$4);\n EventHandler.off(this._dialog, EVENT_KEY$4);\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n handleUpdate() {\n this._adjustDialog();\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop),\n // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element);\n }\n this._element.style.display = 'block';\n this._element.removeAttribute('aria-hidden');\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.scrollTop = 0;\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n if (modalBody) {\n modalBody.scrollTop = 0;\n }\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_SHOW$4);\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate();\n }\n this._isTransitioning = false;\n EventHandler.trigger(this._element, EVENT_SHOWN$4, {\n relatedTarget\n });\n };\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated());\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n if (event.key !== ESCAPE_KEY$1) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n this._triggerBackdropTransition();\n });\n EventHandler.on(window, EVENT_RESIZE$1, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog();\n }\n });\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return;\n }\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition();\n return;\n }\n if (this._config.backdrop) {\n this.hide();\n }\n });\n });\n }\n _hideModal() {\n this._element.style.display = 'none';\n this._element.setAttribute('aria-hidden', true);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n this._isTransitioning = false;\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN);\n this._resetAdjustments();\n this._scrollBar.reset();\n EventHandler.trigger(this._element, EVENT_HIDDEN$4);\n });\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE$3);\n }\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);\n if (hideEvent.defaultPrevented) {\n return;\n }\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const initialOverflowY = this._element.style.overflowY;\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return;\n }\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden';\n }\n this._element.classList.add(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY;\n }, this._dialog);\n }, this._dialog);\n this._element.focus();\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const scrollbarWidth = this._scrollBar.getWidth();\n const isBodyOverflowing = scrollbarWidth > 0;\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n }\n _resetAdjustments() {\n this._element.style.paddingLeft = '';\n this._element.style.paddingRight = '';\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](relatedTarget);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n EventHandler.one(target, EVENT_SHOW$4, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$4, () => {\n if (isVisible(this)) {\n this.focus();\n }\n });\n });\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide();\n }\n const data = Modal.getOrCreateInstance(target);\n data.toggle(this);\n});\nenableDismissTrigger(Modal);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$6 = 'offcanvas';\nconst DATA_KEY$3 = 'bs.offcanvas';\nconst EVENT_KEY$3 = `.${DATA_KEY$3}`;\nconst DATA_API_KEY$1 = '.data-api';\nconst EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst ESCAPE_KEY = 'Escape';\nconst CLASS_NAME_SHOW$3 = 'show';\nconst CLASS_NAME_SHOWING$1 = 'showing';\nconst CLASS_NAME_HIDING = 'hiding';\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\nconst OPEN_SELECTOR = '.offcanvas.show';\nconst EVENT_SHOW$3 = `show${EVENT_KEY$3}`;\nconst EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;\nconst EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;\nconst EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;\nconst EVENT_RESIZE = `resize${EVENT_KEY$3}`;\nconst EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;\nconst SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\nconst Default$5 = {\n backdrop: true,\n keyboard: true,\n scroll: false\n};\nconst DefaultType$5 = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isShown = false;\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$5;\n }\n static get DefaultType() {\n return DefaultType$5;\n }\n static get NAME() {\n return NAME$6;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._backdrop.show();\n if (!this._config.scroll) {\n new ScrollBarHelper().hide();\n }\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.classList.add(CLASS_NAME_SHOWING$1);\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate();\n }\n this._element.classList.add(CLASS_NAME_SHOW$3);\n this._element.classList.remove(CLASS_NAME_SHOWING$1);\n EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n relatedTarget\n });\n };\n this._queueCallback(completeCallBack, this._element, true);\n }\n hide() {\n if (!this._isShown) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._focustrap.deactivate();\n this._element.blur();\n this._isShown = false;\n this._element.classList.add(CLASS_NAME_HIDING);\n this._backdrop.hide();\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n if (!this._config.scroll) {\n new ScrollBarHelper().reset();\n }\n EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n };\n this._queueCallback(completeCallback, this._element, true);\n }\n dispose() {\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n return;\n }\n this.hide();\n };\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop);\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n });\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$3, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus();\n }\n });\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide();\n }\n const data = Offcanvas.getOrCreateInstance(target);\n data.toggle(this);\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show();\n }\n});\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide();\n }\n }\n});\nenableDismissTrigger(Offcanvas);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// js-docs-start allow-list\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\nconst DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n};\n// js-docs-end allow-list\n\nconst uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n\n/**\n * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation\n * contexts.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38\n */\n// eslint-disable-next-line unicorn/better-regex\nconst SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase();\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));\n }\n return true;\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));\n};\nfunction sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml;\n }\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml);\n }\n const domParser = new window.DOMParser();\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase();\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove();\n continue;\n }\n const attributeList = [].concat(...element.attributes);\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName);\n }\n }\n }\n return createdDocument.body.innerHTML;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$5 = 'TemplateFactory';\nconst Default$4 = {\n allowList: DefaultAllowlist,\n content: {},\n // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
'\n};\nconst DefaultType$4 = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n};\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n};\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n }\n\n // Getters\n static get Default() {\n return Default$4;\n }\n static get DefaultType() {\n return DefaultType$4;\n }\n static get NAME() {\n return NAME$5;\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);\n }\n hasContent() {\n return this.getContent().length > 0;\n }\n changeContent(content) {\n this._checkContent(content);\n this._config.content = {\n ...this._config.content,\n ...content\n };\n return this;\n }\n toHtml() {\n const templateWrapper = document.createElement('div');\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template);\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector);\n }\n const template = templateWrapper.children[0];\n const extraClass = this._resolvePossibleFunction(this._config.extraClass);\n if (extraClass) {\n template.classList.add(...extraClass.split(' '));\n }\n return template;\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config);\n this._checkContent(config.content);\n }\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({\n selector,\n entry: content\n }, DefaultContentType);\n }\n }\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template);\n if (!templateElement) {\n return;\n }\n content = this._resolvePossibleFunction(content);\n if (!content) {\n templateElement.remove();\n return;\n }\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement);\n return;\n }\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content);\n return;\n }\n templateElement.textContent = content;\n }\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this]);\n }\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = '';\n templateElement.append(element);\n return;\n }\n templateElement.textContent = element.textContent;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$4 = 'tooltip';\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\nconst CLASS_NAME_FADE$2 = 'fade';\nconst CLASS_NAME_MODAL = 'modal';\nconst CLASS_NAME_SHOW$2 = 'show';\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\nconst EVENT_MODAL_HIDE = 'hide.bs.modal';\nconst TRIGGER_HOVER = 'hover';\nconst TRIGGER_FOCUS = 'focus';\nconst TRIGGER_CLICK = 'click';\nconst TRIGGER_MANUAL = 'manual';\nconst EVENT_HIDE$2 = 'hide';\nconst EVENT_HIDDEN$2 = 'hidden';\nconst EVENT_SHOW$2 = 'show';\nconst EVENT_SHOWN$2 = 'shown';\nconst EVENT_INSERTED = 'inserted';\nconst EVENT_CLICK$1 = 'click';\nconst EVENT_FOCUSIN$1 = 'focusin';\nconst EVENT_FOCUSOUT$1 = 'focusout';\nconst EVENT_MOUSEENTER = 'mouseenter';\nconst EVENT_MOUSELEAVE = 'mouseleave';\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n};\nconst Default$3 = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 6],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
' + '
' + '
' + '
',\n title: '',\n trigger: 'hover focus'\n};\nconst DefaultType$3 = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n};\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n }\n super(element, config);\n\n // Private\n this._isEnabled = true;\n this._timeout = 0;\n this._isHovered = null;\n this._activeTrigger = {};\n this._popper = null;\n this._templateFactory = null;\n this._newContent = null;\n\n // Protected\n this.tip = null;\n this._setListeners();\n if (!this._config.selector) {\n this._fixTitle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$3;\n }\n static get DefaultType() {\n return DefaultType$3;\n }\n static get NAME() {\n return NAME$4;\n }\n\n // Public\n enable() {\n this._isEnabled = true;\n }\n disable() {\n this._isEnabled = false;\n }\n toggleEnabled() {\n this._isEnabled = !this._isEnabled;\n }\n toggle() {\n if (!this._isEnabled) {\n return;\n }\n this._activeTrigger.click = !this._activeTrigger.click;\n if (this._isShown()) {\n this._leave();\n return;\n }\n this._enter();\n }\n dispose() {\n clearTimeout(this._timeout);\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));\n }\n this._disposePopper();\n super.dispose();\n }\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements');\n }\n if (!(this._isWithContent() && this._isEnabled)) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));\n const shadowRoot = findShadowRoot(this._element);\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);\n if (showEvent.defaultPrevented || !isInTheDom) {\n return;\n }\n\n // TODO: v6 remove this or make it optional\n this._disposePopper();\n const tip = this._getTipElement();\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'));\n const {\n container\n } = this._config;\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip);\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));\n }\n this._popper = this._createPopper(tip);\n tip.classList.add(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));\n if (this._isHovered === false) {\n this._leave();\n }\n this._isHovered = false;\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n hide() {\n if (!this._isShown()) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));\n if (hideEvent.defaultPrevented) {\n return;\n }\n const tip = this._getTipElement();\n tip.classList.remove(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n this._activeTrigger[TRIGGER_CLICK] = false;\n this._activeTrigger[TRIGGER_FOCUS] = false;\n this._activeTrigger[TRIGGER_HOVER] = false;\n this._isHovered = null; // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return;\n }\n if (!this._isHovered) {\n this._disposePopper();\n }\n this._element.removeAttribute('aria-describedby');\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n update() {\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle());\n }\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());\n }\n return this.tip;\n }\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml();\n\n // TODO: remove this check in v6\n if (!tip) {\n return null;\n }\n tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n // TODO: v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`);\n const tipId = getUID(this.constructor.NAME).toString();\n tip.setAttribute('id', tipId);\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE$2);\n }\n return tip;\n }\n setContent(content) {\n this._newContent = content;\n if (this._isShown()) {\n this._disposePopper();\n this.show();\n }\n }\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content);\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n });\n }\n return this._templateFactory;\n }\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n };\n }\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n }\n _isAnimated() {\n return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);\n }\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);\n }\n _createPopper(tip) {\n const placement = execute(this._config.placement, [this, tip, this._element]);\n const attachment = AttachmentMap[placement.toUpperCase()];\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment));\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this._element]);\n }\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [{\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }, {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n }, {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement);\n }\n }]\n };\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _setListeners() {\n const triggers = this._config.trigger.split(' ');\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context.toggle();\n });\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);\n const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n context._enter();\n });\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n context._leave();\n });\n }\n }\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide();\n }\n };\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n }\n _fixTitle() {\n const title = this._element.getAttribute('title');\n if (!title) {\n return;\n }\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title);\n }\n this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title');\n }\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true;\n return;\n }\n this._isHovered = true;\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show();\n }\n }, this._config.delay.show);\n }\n _leave() {\n if (this._isWithActiveTrigger()) {\n return;\n }\n this._isHovered = false;\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide();\n }\n }, this._config.delay.hide);\n }\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout);\n this._timeout = setTimeout(handler, timeout);\n }\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true);\n }\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element);\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute];\n }\n }\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n };\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container);\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n };\n }\n if (typeof config.title === 'number') {\n config.title = config.title.toString();\n }\n if (typeof config.content === 'number') {\n config.content = config.content.toString();\n }\n return config;\n }\n _getDelegateConfig() {\n const config = {};\n for (const [key, value] of Object.entries(this._config)) {\n if (this.constructor.Default[key] !== value) {\n config[key] = value;\n }\n }\n config.selector = false;\n config.trigger = 'manual';\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config;\n }\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy();\n this._popper = null;\n }\n if (this.tip) {\n this.tip.remove();\n this.tip = null;\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$3 = 'popover';\nconst SELECTOR_TITLE = '.popover-header';\nconst SELECTOR_CONTENT = '.popover-body';\nconst Default$2 = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
' + '
' + '

' + '
' + '
',\n trigger: 'click'\n};\nconst DefaultType$2 = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n};\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default$2;\n }\n static get DefaultType() {\n return DefaultType$2;\n }\n static get NAME() {\n return NAME$3;\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent();\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n };\n }\n _getContent() {\n return this._resolvePossibleFunction(this._config.content);\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$2 = 'scrollspy';\nconst DATA_KEY$2 = 'bs.scrollspy';\nconst EVENT_KEY$2 = `.${DATA_KEY$2}`;\nconst DATA_API_KEY = '.data-api';\nconst EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\nconst EVENT_CLICK = `click${EVENT_KEY$2}`;\nconst EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\nconst CLASS_NAME_ACTIVE$1 = 'active';\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\nconst SELECTOR_TARGET_LINKS = '[href]';\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\nconst SELECTOR_NAV_LINKS = '.nav-link';\nconst SELECTOR_NAV_ITEMS = '.nav-item';\nconst SELECTOR_LIST_ITEMS = '.list-group-item';\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;\nconst SELECTOR_DROPDOWN = '.dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\nconst Default$1 = {\n offset: null,\n // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n};\nconst DefaultType$1 = {\n offset: '(number|null)',\n // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n};\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map();\n this._observableSections = new Map();\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;\n this._activeTarget = null;\n this._observer = null;\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n };\n this.refresh(); // initialize\n }\n\n // Getters\n static get Default() {\n return Default$1;\n }\n static get DefaultType() {\n return DefaultType$1;\n }\n static get NAME() {\n return NAME$2;\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables();\n this._maybeEnableSmoothScroll();\n if (this._observer) {\n this._observer.disconnect();\n } else {\n this._observer = this._getNewObserver();\n }\n for (const section of this._observableSections.values()) {\n this._observer.observe(section);\n }\n }\n dispose() {\n this._observer.disconnect();\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body;\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));\n }\n return config;\n }\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return;\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK);\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash);\n if (observableSection) {\n event.preventDefault();\n const root = this._rootElement || window;\n const height = observableSection.offsetTop - this._element.offsetTop;\n if (root.scrollTo) {\n root.scrollTo({\n top: height,\n behavior: 'smooth'\n });\n return;\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height;\n }\n });\n }\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n };\n return new IntersectionObserver(entries => this._observerCallback(entries), options);\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop;\n this._process(targetElement(entry));\n };\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;\n this._previousScrollData.parentScrollTop = parentScrollTop;\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null;\n this._clearActiveClass(targetElement(entry));\n continue;\n }\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry);\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return;\n }\n continue;\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry);\n }\n }\n }\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map();\n this._observableSections = new Map();\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue;\n }\n const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(decodeURI(anchor.hash), anchor);\n this._observableSections.set(anchor.hash, observableSection);\n }\n }\n }\n _process(target) {\n if (this._activeTarget === target) {\n return;\n }\n this._clearActiveClass(this._config.target);\n this._activeTarget = target;\n target.classList.add(CLASS_NAME_ACTIVE$1);\n this._activateParents(target);\n EventHandler.trigger(this._element, EVENT_ACTIVATE, {\n relatedTarget: target\n });\n }\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);\n return;\n }\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both